Skip to content

Repository files navigation

confkit

CI Go Reference

Typed configuration loading and validation for Go services.

confkit defines the environment variables a service expects, validates them at startup, assigns typed values into a struct, and can generate .env.example or Markdown documentation from the same contract.

It is intentionally env-first. It does not try to be a full configuration system for every backend or file format.

Install

go get github.com/ahmertsengol/confkit

Usage

package main

import (
	"log"

	conf "github.com/ahmertsengol/confkit"
)

type Config struct {
	Port        int
	DatabaseURL string
	JWTSecret   string
	Env         string
}

func main() {
	cfg, err := conf.Load[Config](conf.Contract(
		conf.Int("PORT").
			Default(8080).
			Min(1).
			Max(65535).
			Description("HTTP server port"),

		conf.String("DATABASE_URL").
			Required().
			URL().
			Description("Primary database connection URL"),

		conf.String("JWT_SECRET").
			Required().
			Min(32).
			Secret().
			Description("JWT signing secret"),

		conf.Enum("ENV", "development", "staging", "production").
			Default("development"),
	).Strict(), conf.WithDotEnv(".env"))
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("starting %s service on port %d", cfg.Env, cfg.Port)
}

Example error:

Invalid configuration:

DATABASE_URL
  Required environment variable is missing.

PORT
  Expected integer, got "abc".

JWT_SECRET
  Must be at least 32 characters. Current value: [REDACTED].

Loading rules

Load reads values in this order:

defaults < dotenv files < process environment < explicit sources
  • WithDotEnv(".env") ignores a missing file.
  • WithRequiredDotEnv(path) returns an error if the file cannot be read.
  • WithSource(MapSource(...)) is useful for tests and explicit overrides.
  • Secret fields are redacted in errors and generated examples.
  • Contract errors, parse errors, and validation errors are returned together as *confkit.Error.
  • Contract(...).Strict() rejects exported struct fields that are not present in the contract.
  • Generated examples validate defaults and quote values when needed so the output can be read back by confkit.
  • List defaults used for generated examples must not contain the list separator.
  • Custom validators should be pure predicates; they may run during loading and documentation generation.

Dotenv support is intentionally minimal and meant for local development. It supports common KEY=value, export KEY=value, quoted values, and inline comments. For advanced dotenv behavior, load values with another package and pass them through WithSource.

For small programs that only need typed env parsing:

type Config struct {
	Port        int    `conf:"PORT"`
	ServiceName string // SERVICE_NAME
	Debug       bool   `conf:"DEBUG"`
}

cfg, err := conf.LoadEnv[Config]()

LoadEnv does not apply contract validation, required fields, defaults, or secret redaction. Fields without a conf tag use screaming snake case; tags are only needed when the environment key should differ from the field name.

Generated files

The contract can be used to generate .env.example:

_ = conf.WriteExample(contract, os.Stdout)
# HTTP server port
PORT=8080

# Primary database connection URL
DATABASE_URL=

# JWT signing secret
JWT_SECRET=

It can also generate Markdown documentation:

_ = conf.WriteMarkdown(contract, os.Stdout)
| Key | Type | Required | Default | Secret | Description |
|---|---|---|---|---|---|
| PORT | int | no | 8080 | no | HTTP server port |

Supported API

Category API
Field types String, Int, Float, Bool, Duration, Enum, List
Contract options Strict
Modifiers Required, Optional, Default, Secret, Description, Desc
Validators Min, Max, Regex, URL, Email, Hostname, IP, NonEmpty, Validate for typed custom rules, enum membership through Enum

Notes

  • Duplicate contract keys are rejected.
  • Duplicate struct field mappings are rejected.
  • Invalid regex validators return contract errors instead of panicking.
  • Strict mode can reject struct fields missing from the contract.
  • conf:"-" skips a struct field.
  • Remote providers, hot reload, Vault, Consul, and Kubernetes integrations are outside the current package scope.

About

Typed, validated, secret-safe configuration contracts for Go services.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages