Skip to content

Home

Confii

Complete Configuration Management for Go

Go Reference CI Coverage Go Report Card OpenSSF Scorecard License


Confii loads, merges, validates, and manages configuration from any source — YAML, JSON, TOML, INI, .env files, environment variables, HTTP endpoints, and cloud stores — with type-safe generics, secret resolution, source tracking, drift detection, and versioning.

Features

  • Multi-source loading — YAML, JSON, TOML, INI, .env, env vars, HTTP, S3, SSM, Azure Blob, GCS, IBM COS, Git
  • Type-safe genericsConfig[T] with cfg.Typed() returning *T and full IDE autocomplete
  • 6 merge strategies — replace, merge, append, prepend, intersection, union — with per-path overrides
  • Secret resolution${secret:key} placeholders from AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault (9 auth methods)
  • Config composition — Hydra-style _include and _defaults directives with cycle detection
  • Environment resolution — Automatic default + production/staging merging
  • Hook system — 4 types (key, value, condition, global) for value transformation on access
  • IntrospectionExplain(), Layers(), Schema(), source tracking, override history
  • Drift detection — Diff configs, detect unintended changes, version with rollback
  • Dynamic reloading — File watching via fsnotify, incremental reload (mtime + SHA256)
  • Observability — Access metrics, event emission, change callbacks
  • CLI tool — 10 commands: load, get, validate, export, diff, debug, explain, lint, docs, migrate
  • Thread-safesync.RWMutex, zero global state, safe for concurrent reads

Install

go get github.com/confiify/confii-go

Quick Start

cfg, err := confii.New[any](context.Background(),
    confii.WithLoaders(
        loader.NewYAML("config.yaml"),
        loader.NewEnvironment("APP"),
    ),
    confii.WithEnv("production"),
)
if err != nil {
    log.Fatal(err)
}

host, _ := cfg.Get("database.host")
port := cfg.GetIntOr("database.port", 5432)
debug := cfg.GetBoolOr("debug", false)
type AppConfig struct {
    Database struct {
        Host string `mapstructure:"host" validate:"required"`
        Port int    `mapstructure:"port" validate:"required,min=1,max=65535"`
    } `mapstructure:"database"`
    Debug bool `mapstructure:"debug"`
}

cfg, err := confii.New[AppConfig](ctx,
    confii.WithLoaders(loader.NewYAML("config.yaml")),
    confii.WithValidateOnLoad(true),
)

model, _ := cfg.Typed()
fmt.Println(model.Database.Host) // IDE autocomplete works

Drop a .confii.yaml in your project root — zero Go code to configure Confii itself:

.confii.yaml
# Confii finds this file automatically
default_environment: production
env_switcher: APP_ENV
validate_on_load: true
use_env_expander: true
freeze_on_load: true
deep_merge: true
log_level: warn
schema_path: schema.json

sources:
  - type: yaml
    path: config/base.yaml
  - type: yaml
    path: config/prod.yaml
  - type: env
    prefix: APP

secrets:
  provider: vault
  address: https://vault.internal:8200
  auth: kubernetes
main.go
// That's it — Confii reads .confii.yaml automatically
cfg, err := confii.New[AppConfig](ctx)
if err != nil {
    log.Fatal(err)
}
model, _ := cfg.Typed()

No WithLoaders(), no WithEnv(), no WithValidateOnLoad() — everything is declared in the config file. Constructor arguments still override self-config values when you need them.

cfg, err := confii.NewBuilder[AppConfig]().
    WithEnv("production").
    AddLoader(loader.NewYAML("base.yaml")).
    AddLoader(loader.NewYAML("prod.yaml")).
    EnableFreezeOnLoad().
    Build(ctx)

Full Quick Start Guide View Examples