goconfig is a lightweight Go library that fills structs from:
- JSON config file
- Environment variables
- Command-line flags
It is designed for apps that want production-ready configuration with minimal boilerplate.
go get github.com/fulldump/goconfigpackage main
import (
"log"
"time"
"github.com/fulldump/goconfig"
)
type DB struct {
Host string `usage:"Database host"`
Port int `usage:"Database port"`
}
type Config struct {
ServiceName string `usage:"Service name"`
Timeout time.Duration `usage:"Request timeout"`
DB DB
}
func main() {
cfg := Config{
ServiceName: "payments",
Timeout: 5 * time.Second,
DB: DB{
Host: "localhost",
Port: 5432,
},
}
if err := goconfig.Load(&cfg); err != nil {
log.Fatal(err)
}
}If you want legacy one-liner behaviour (exit on error):
goconfig.Read(&cfg)type Config struct {
HTTPPort int `usage:"HTTP port"`
Timeout time.Duration `usage:"Request timeout"`
DB struct {
Host string `usage:"Database host"`
Port int `usage:"Database port"`
}
}
cfg := Config{HTTPPort: 8080, Timeout: 3 * time.Second}
if err := goconfig.Load(&cfg); err != nil {
log.Fatal(err)
}type Config struct {
Concurrency int `usage:"Worker concurrency"`
PollEvery time.Duration `usage:"Polling interval"`
Queues []string `usage:"Enabled queues"`
}
cfg := Config{Concurrency: 4, PollEvery: 2 * time.Second}
if err := goconfig.Load(&cfg); err != nil {
log.Fatal(err)
}Environment example:
export QUEUES='["emails", "billing"]'
export CONCURRENCY=8cfg := Config{}
err := goconfig.Load(&cfg,
goconfig.WithArgs([]string{"-verbose", "-config", "./testdata/config.json"}),
goconfig.WithEnvLookup(func(k string) (string, bool) {
if k == "VERBOSE" {
return "true", true
}
return "", false
}),
goconfig.WithoutImplicitConfigFile(),
)Highest priority wins:
- Command-line flags
- Environment variables
- JSON config file
- Struct default values
If -config is not provided and ./config.json exists in the current working
directory, goconfig loads it automatically before env vars and flags.
Given this struct:
type Config struct {
App struct {
Port int
}
}- Flag name:
-app.port - Environment variable:
APP_PORT - JSON object:
{
"app": {
"port": 8080
}
}-help: displays generated help with usage and env names-config: JSON file path to load before env and flags
When -config is not set, goconfig auto-loads config.json if it exists.
- bool
- string
- float32, float64
- int, int32, int64
- uint, uint32, uint64
- slices (
[]T, as JSON arrays for env/flags) - nested structs
- pointers to structs
time.Duration(duration string like"15s"or nanoseconds)
Load returns errors instead of exiting. This is the recommended API for
libraries and services.
err := goconfig.Load(&cfg)Optional behavior can be controlled with options:
WithArgs([]string)WithProgramName("myapp")WithConfigFile("/etc/myapp/config.json")WithConfigFlagName("settings")WithImplicitConfigFile("myconfig.json")WithoutImplicitConfigFile()WithEnvLookup(func(string) (string, bool))
Read keeps backward compatibility and exits process on error.
goconfig.Read(&cfg)- Minimal integration cost for existing Go projects
- Predictable override order across local/dev/prod
- Built-in generated help for operations teams
- No external runtime dependencies
go test ./...For local workflows:
make test
make coverage- CI: GitHub Actions (
.github/workflows/ci.yml) - Contributing guide:
CONTRIBUTING.md - Code of conduct:
CODE_OF_CONDUCT.md - Security policy:
SECURITY.md - Changelog:
CHANGELOG.md - Release process:
RELEASING.md - Launch/promotion plan:
PROMOTION_PLAN.md - Issue and PR templates:
.github/ISSUE_TEMPLATEand.github/pull_request_template.md
Issues and pull requests are welcome.
See ROADMAP.md for the proposed adoption roadmap and high-impact issues.
MIT License. See LICENSE.
