v0.9.0 — Production Ready

Typed config
for Go, done right.

Load from YAML, env, JSON, TOML, Vault, AWS, or Kubernetes. Validate with struct tags. Redact secrets automatically. Get human-readable errors, not stack traces.

go get github.com/MimoJanra/confkit
0.9.0Latest
MITLicense
2Core deps
1.24+Go version
Why it works

Everything you need.
Nothing you don't.

Typed config with batteries included — validation, secrets, multi-source merging — without assembling multiple libraries by hand.

🎯

Fully Typed

Load[T] returns your exact struct — not map[string]interface{}. Types checked at compile time. No casting, no panics.

Validation via Tags

Rules in struct tags: validate:"required,min=1,max=65535". No extra config files. Custom validators per load call. Cross-field validation.

💬

Human-Readable Errors

Know which field failed, which rule, and which source. Explain(err) gives actionable messages, not cryptic stack traces.

🔒

Secret Redaction

Tag any field secret:"true". Automatically redacted in errors, dumps, and logs. No secrets ever leak. Audit trail available.

🔌

Multi-Source Merging

YAML, env, JSON, TOML, flags, Kubernetes, Vault, AWS — in explicit priority order. First source per field wins.

Lightweight Core

Only yaml.v3 + go-toml in core. Cloud integrations are optional modules — pull only what you need.

Quick Start

Up and running
in 30 seconds.

Define your struct once. Defaults and validation live in the tags.

1

Install

go get github.com/MimoJanra/confkit

2

Define your config struct

Annotate fields with env, default, validate, and secret tags.

3

Call confkit.Load[T](...)

Pass sources in priority order. Get back your typed struct or a clear error.

4

Handle errors with Explain(err)

One call gives a human-readable message safe to log.Fatal — secrets redacted.

type Config struct {
    Host    string        `env:"HOST"    default:"localhost"`
    Port    int           `env:"PORT"    default:"8080" validate:"min=1,max=65535"`
    Timeout time.Duration `env:"TIMEOUT" default:"30s"`
    DB struct {
        DSN      string `env:"DSN"       validate:"required" secret:"true"`
        MaxConns int    `env:"MAX_CONNS" default:"10" validate:"min=1,max=100"`
    } `prefix:"DB_"`
}

cfg, err := confkit.Load[Config](
    confkit.FromFlags(),
    confkit.FromEnv(),
    confkit.FromYAML("config.yaml"),
)
if err != nil {
    log.Fatal(confkit.Explain(err))
}
type Config struct {
    Server struct {
        Addr string `env:"ADDR" default:":8080"`
        TLS  bool   `env:"TLS"  default:"false"`
    }
    Database struct {
        URL      string `env:"URL"       validate:"required" secret:"true"`
        MaxConns int    `env:"MAX_CONNS" default:"10"`
    }
}
cfg, err := confkit.Load[Config](confkit.FromEnv())
// SERVER_ADDR=:3000
// DATABASE_URL=postgres://user:pass@localhost/db
// DATABASE_MAX_CONNS=20
type Config struct {
    Verbose  bool   `flag:"verbose" short:"v"`
    Output   string `flag:"output"  short:"o" default:"stdout"`
    InputDir string `flag:"input"   validate:"required"`
}
cfg, err := confkit.Load[Config](confkit.FromFlags())
// ./mytool -v -o report.txt --input /data
import "github.com/MimoJanra/confkit/vault"

type Config struct {
    API struct {
        Key    string `validate:"required" secret:"true"`
        Secret string `validate:"required" secret:"true"`
    }
}

auth := vault.VaultTokenAuth(os.Getenv("VAULT_TOKEN"))
cfg, err := confkit.Load[Config](
    vault.FromVault("https://vault.example.com", auth, "/secret/myapp"),
)
// Priority: env → env-specific YAML → defaults
cfg, err := confkit.Load[Config](
    confkit.FromEnv(),
    confkit.FromYAML("config."+os.Getenv("ENV")+".yaml"),
    confkit.FromYAML("config.defaults.yaml"),
)
// ENV=prod → config.prod.yaml
// ENV=dev  → config.dev.yaml
// Fallback: config.defaults.yaml
Why confkit

No more assembling
libraries by hand.

confkit gives you typed config with validation, defaults, and safe error messages — all from a single struct definition.

Comparison of Go configuration libraries
FeatureconfkitViperenvconfigkoanf
Typed Load[T]⚠️
Defaults via struct tags⚠️
Built-in validation rules
Secret redaction
Multi-source merging⚠️
Lightweight core
Cloud integrationsoptional modulesbundledN/Aoptional
Runtime hot reload⚠️
Use Viper if…

you need heavy runtime reloading with watches across many files and don't need validation or type safety.

Use envconfig if…

you only care about environment variables and simple type conversion — nothing else.

Use koanf if…

you want extreme modularity and don't need validation, secret redaction, or typed loading.

Use confkit if…

you want one struct for all config, built-in validation, safe error messages, and optional cloud sources.

Sources

Load from anywhere.

Built-in sources cover the common cases. Cloud integrations are optional modules — each a separate go get.

Built-in

  • 📄
    YAMLconfkit.FromYAML(path)
    core
  • 📋
    JSONconfkit.FromJSON(path)
    core
  • ⚙️
    TOMLconfkit.FromTOML(path)
    core
  • 🌍
    Environment Variablesconfkit.FromEnv()
    core
  • 🚩
    CLI Flagsconfkit.FromFlags()
    core

Optional cloud modules

  • ☸️
    Kubernetes ConfigMapk8s.FromKubernetesConfigMap(...)
    confkit/k8s
  • 🔑
    HashiCorp Vaultvault.FromVault(...)
    confkit/vault
  • 🗂️
    Consul KVconsul.FromConsul(...)
    confkit/consul
  • 🔧
    etcd v3etcd.FromEtcd(endpoints)
    confkit/etcd
  • ☁️
    AWS SSM & Secrets Manageraws.FromAWSSecretsManager(...)
    confkit/aws
Validation & Tags

Rules in the struct.
Errors for humans.

Validation Rules

RuleTypesBehaviour
requiredanyNon-zero value required
min=Nint, floatValue ≥ N
min=NstringLength ≥ N characters
max=Nint, floatValue ≤ N
max=NstringLength ≤ N characters
oneof=a b cstringMust equal one of the options
emailstringValid email address
http_urlstringValid HTTP/HTTPS URL
ip, ipv4, ipv6stringValid IP address
uuidstringValid UUID v1–v5
portint, stringValid port 1–65535
regex=patternstringMust match regexp

Rules are comma-separated: validate:"required,min=1,max=65535"

Struct Tag Reference

env:"VAR_NAME"

Read from environment variable

flag:"flag-name"

Read from CLI flag --flag-name

default:"value"

Use when no source provides a value

validate:"rules"

Validation rules, comma-separated

secret:"true"

Redact in errors, dumps & logs

prefix:"PREFIX_"

Prepend to env names in nested struct

help:"description"

Shown in schema and CLI help

short:"f"

Single-character short flag -f