Go (Golang) Application Configuration: Overview of Libraries and Tools
Developing modern applications in Go (Golang) requires flexible and reliable configuration management. Settings can come from environment variables, files (JSON, YAML, TOML), command-line flags, or remote sources. In this article, we will review key libraries and tools for configuring Go applications, their features, usage examples, and recommendations for selection.
Why is a separate configuration library needed?
Go's built-in tools (e.g., the os or flag package) allow reading environment variables and flags, but this is insufficient for complex projects. Third-party libraries provide:
- Support for multiple sources (files, env, etcd, Consul).
- Automatic binding of struct fields to configuration.
- Value validation.
- Hot reloading (watch) of changes.
1. Viper — The Universal King of Configuration
Viper is the most popular configuration library in Go (over 25k stars on GitHub). It supports YAML, JSON, TOML, HCL, INI, envfile, environment variables, and remote systems (etcd, Consul).
Installation
go get github.com/spf13/viperUsage Example
package main
import ( "fmt" "github.com/spf13/viper")
type Config struct { Port int `mapstructure:"port"` DBHost string `mapstructure:"db_host"` Debug bool `mapstructure:"debug"`}
func main() { viper.SetConfigName("config") // file name without extension viper.SetConfigType("yaml") viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil { panic(fmt.Errorf("error reading config: %w", err)) }
var cfg Config if err := viper.Unmarshal(&cfg); err != nil { panic(fmt.Errorf("unmarshal error: %w", err)) }
fmt.Printf("Port: %d, DB Host: %s, Debug: %t", cfg.Port, cfg.DBHost, cfg.Debug)}Advantages: huge community, support for multiple formats, ability to override via environment variables.
Disadvantages: overkill for simple projects, complexity in debugging source priorities.
2. envconfig — Simplicity for Environment Variables
The envconfig library (by kelseyhightower) is designed for reading configuration exclusively from environment variables. Minimalism and speed are its main strengths.
Installation
go get github.com/kelseyhightower/envconfigExample
package main
import ( "fmt" "github.com/kelseyhightower/envconfig")
type Config struct { Port int `envconfig:"PORT" default:"8080"` DBHost string `envconfig:"DB_HOST" required:"true"` Debug bool `envconfig:"DEBUG"`}
func main() { var cfg Config err := envconfig.Process("myapp", &cfg) if err != nil { panic(err) } fmt.Printf("Port: %d, Host: %s, Debug: %t", cfg.Port, cfg.DBHost, cfg.Debug)}Environment variables will have the prefix MYAPP_ (e.g., MYAPP_PORT).
Pros: zero dependencies, simplicity, automatic validation of required fields.
Cons: only environment variables, no support for files or flags.
3. cleanenv — Lightweight and Readable
Cleanenv (by Ilya Kaznacheev) is another minimalist tool that supports reading from env and YAML/JSON files. Its feature is built-in support for descriptions and help.
Installation
go get github.com/ilyakaznacheev/cleanenvExample
package main
import ( "fmt" "github.com/ilyakaznach Also in library
Data Validation in Go (Golang): Libraries, Approaches, and Code Examples
Working with Dates in JavaScript (Node.js): Best Libraries
HTTP Client for C++: Top Libraries for Network Programming
Working with Excel in PHP: PhpSpreadsheet and OpenSpout Libraries