Socket
Book a DemoInstallSign in
Socket

github.com/adnsv/confkit

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/adnsv/confkit

Source
Go
Version
v0.1.2
Version published
Created
Source

Confkit

Go Reference

A minimalist Go configuration library with transparent layering.

What Confkit Is (and Isn't)

Confkit embraces simplicity over features. While other configuration libraries offer dozens of integrations, complex validation rules, and automatic reloading, confkit provides just the essentials:

  • Everything is a string until you need it to be something else
  • Layers are just maps that you can inspect, modify, and debug
  • Keys are normalized so server.port, SERVER_PORT, and server-port are the same
  • Source tracking tells you exactly where each value came from
  • No magic - no reflection on your types, no struct tags for defaults, no hidden behavior
// See exactly what's happening
fmt.Printf("%+v\n", cfg.Layers)  // It's just data

// Know where values come from
value, originalKey, sourceName, _ := cfg.Get("server.port")
// value="8080", originalKey="SERVER_PORT", sourceName="env"

Why Another Config Library?

Most configuration libraries are either too simple (just os.Getenv) or too complex (hundreds of features you'll never use). Confkit sits in the sweet spot:

  • Transparent: Inspect your entire config state. Examine every layer. Track value origins for audit trails, config documentation, or troubleshooting.
  • Composable: Layers are just map[string]string. Create them however you want.
  • Predictable: Later layers win. Keys are normalized. That's it.
  • Runtime-friendly: Modify layers after adding them - perfect for feature flags or admin overrides.
  • Type-safe: Unmarshal to structs when you need to, with full mapstructure support.

Core Features

  • Layered configuration with clear precedence (last layer wins)
  • String-based storage for universal compatibility
  • Source tracking - know exactly where each value came from
  • Key normalization - server.port = SERVER_PORT = server-port
  • Runtime modification - layers are mutable, perfect for feature flags
  • Type-safe unmarshaling via mapstructure, when you need it
  • Zero magic - no struct tags for defaults, no hidden behavior

Works With Everything

Confkit doesn't parse files or connect to databases - it just manages string key-value pairs. This means it works seamlessly with whatever you're already using:

// From JSON/YAML/TOML files
var data map[string]any
json.Unmarshal(configBytes, &data)
cfg.Add(confkit.FromMap("config.json", data))

// From SQL databases
rows := db.Query("SELECT key, value FROM settings WHERE app = ?", appID)
cfg.Add(confkit.FromMap("database", sqlRowsToMap(rows)))

// From Redis, etcd, Consul
values := consul.GetAll("myapp/config")
cfg.Add(&confkit.Layer{Name: "consul", Values: values})

// From your custom API
settings := apiClient.GetSettings()
cfg.Add(confkit.FromMap("api", settings))

The flat map[string]string design means confkit works with any storage system that can produce key-value pairs.

Installation

go get github.com/adnsv/confkit

Quick Example

// Define your configuration struct
type Config struct {
    Server struct {
        Port int `mapstructure:"port"`
        Host string `mapstructure:"host"`
    } `mapstructure:"server"`
}

// Create defaults using a function (testable, reusable)
func DefaultConfig() *Config {
    return &Config{
        Server: struct{
            Port int `mapstructure:"port"`
            Host string `mapstructure:"host"`
        }{
            Port: 8080,
            Host: "localhost",
        },
    }
}

// Build configuration with clear precedence
cfg := confkit.NewConfig()

// Layer 1: Defaults
defaults := cfg.Add(confkit.FromDefaults("defaults", DefaultConfig()))

// Layer 2: Config file (you load it however you want)
configData := loadMyConfigFile() // Returns map[string]any
cfg.Add(confkit.FromMap("config.json", configData))

// Layer 3: Environment (highest precedence)
cfg.Add(confkit.FromEnv("env", "MYAPP_"))

// Use it - multiple ways
var config Config
cfg.Unmarshal(&config)

// Or get individual values with full visibility
port, originalKey, source, _ := cfg.Get("server.port")
fmt.Printf("Port %s came from %s (via %s)\n", port, source, originalKey)

// Runtime updates? Just modify the layer
defaults.Values["feature.newThing"] = "enabled"

The Confkit Philosophy

Simple is harder than complex. Every feature in confkit must justify its existence without compromising the core simplicity.

Transparency over magic. You should be able to access your configuration state and understand it completely. No hidden state, no surprising behavior.

Composition over configuration. Confkit provides building blocks that combine into complete solutions. Start simple, add only what you need.

Strings are universal. Every system understands strings. Type conversion happens at the edges, not in the core.

Documentation

Dependencies

License

MIT

FAQs

Package last updated on 18 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts