Tame Your Go Config Chaos with Koanf
Ever found yourself wrestling with configuration in your Go applications? You start with environment variables, then need a config file, maybe some command-line flags, and suddenly you're stitching together three different libraries and writing a bunch of glue code. It feels like more work than the feature you're trying to configure.
What if you could pull configuration from anywhere—JSON, YAML, environment variables, command line, even remote sources like etcd or Vault—using a single, consistent, and lightweight interface? That's the promise of Koanf.
What It Does
Koanf is a lean, yet powerful library for managing configuration in Go applications. Its core job is simple: to help you read configuration settings from multiple sources and merge them into a single, coherent structure. The "zero bloat" part isn't just marketing; it has no external dependencies outside the Go standard library for its core functionality.
You define what configuration sources matter to your app (a default config file, environment-specific overrides, command-line flags). Koanf loads them in your specified order, with later sources automatically overriding values from earlier ones. You then access your config through a straightforward API, using dotted paths like app.server.port.
Why It's Cool
The magic of Koanf is in its elegant simplicity and its powerful provider system.
First, it's incredibly modular. The core koanf package is just the brain for parsing and managing key-value pairs. To actually read config, you plug in "providers." There's a provider for almost everything: files (JSON, YAML, TOML, dotenv), environment variables (with optional prefixing and automatic key delimiting), command-line flags (using the standard flag package or POSIX-style with pflag), and even remote systems like HashiCorp Vault or etcd. You can chain them together effortlessly.
Second, the merging behavior is exactly what you want. A common pattern is to load default configs from a file, then override them with environment variables (perfect for 12-factor apps), and finally let command-line flags take ultimate precedence. Koanf handles this hierarchy cleanly.
Finally, it plays nicely with the rest of the Go ecosystem. You can unmarshal your entire config into a Go struct, or watch a file for changes in real-time. It gives you the flexibility of unstructured access (koanf.Int("app.port")) with the safety and convenience of structured unmarshaling.
How to Try It
Getting started is a three-step process: install the core library and the providers you need, set them up, and start reading config.
go get github.com/knadh/koanf/parsers/yaml
go get github.com/knadh/koanf/providers/file
go get github.com/knadh/koanf/v2
Here's a quick example that loads a YAML file and then overrides it with environment variables:
package main
import (
"fmt"
"log"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/v2"
)
func main() {
var k = koanf.New(".")
// Load YAML config from file
if err := k.Load(file.Provider("config.yaml"), yaml.Parser()); err != nil {
log.Fatalf("error loading config: %v", err)
}
// At this point, you can read config
fmt.Println("Database host:", k.String("database.host"))
}
Check out the Koanf GitHub repository for comprehensive documentation, more provider examples, and advanced patterns like configuration watching.
Final Thoughts
In a world where applications are deployed across diverse environments, a solid configuration strategy is non-negotiable. Koanf gets out of your way and just solves the problem. It doesn't force a paradigm on you; it just gives you the tools to build the config loading pipeline that fits your app perfectly.
If you're tired of cobbling together config solutions or using a library that feels heavier than it needs to be, give Koanf a look. It's one of those tools that does its job so well, you'll forget it's even there—which is exactly what a good library should do.
@githubprojects
Repository: https://github.com/knadh/koanf