goconfig

package module
v1.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 11 Imported by: 14

README

Goconfig

Logo

CI Go Reference Go Report Card MIT License

goconfig is a lightweight Go library that fills structs from:

  1. JSON config file
  2. Environment variables
  3. Command-line flags

It is designed for apps that want production-ready configuration with minimal boilerplate.

Installation

go get github.com/fulldump/goconfig

Quick Start

package 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)

Copy/Paste Recipes

1) API service
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)
}
2) Worker service
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=8
3) CLI tool with deterministic args/env (tests)
cfg := 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(),
)

Precedence

Highest priority wins:

  1. Command-line flags
  2. Environment variables
  3. JSON config file
  4. 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.

Naming Convention

Given this struct:

type Config struct {
	App struct {
		Port int
	}
}
  • Flag name: -app.port
  • Environment variable: APP_PORT
  • JSON object:
{
  "app": {
    "port": 8080
  }
}

Built-in Flags

  • -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.

Supported Types

  • 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)

Public API

Load

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

Read keeps backward compatibility and exits process on error.

goconfig.Read(&cfg)

Why Teams Use goconfig

  • 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

Development

go test ./...

For local workflows:

make test
make coverage

Open Source Health

  • 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_TEMPLATE and .github/pull_request_template.md

Contributing

Issues and pull requests are welcome.

Roadmap

See ROADMAP.md for the proposed adoption roadmap and high-impact issues.

License

MIT License. See LICENSE.

Documentation

Overview

Package goconfig loads configuration values into Go structs from three sources: JSON config files, environment variables and command-line flags.

Sources are applied in this order:

  1. JSON file
  2. Environment variables
  3. Command-line flags

This means command-line flags have the highest precedence.

Quick start:

type Config struct {
	Port int `usage:"HTTP port"`
}

cfg := Config{Port: 8080}
if err := goconfig.Load(&cfg); err != nil {
	log.Fatal(err)
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FillArgs added in v1.1.0

func FillArgs(c interface{}, args []string) error

func FillEnvironments added in v1.1.0

func FillEnvironments(c interface{}) (err error)

func FillJson added in v1.1.0

func FillJson(c interface{}, filename string) error

func Load added in v1.8.0

func Load(c interface{}, opts ...Option) error

Load populates c from JSON config file, environment variables and command-line flags.

Priority order (highest to lowest): flags > environment > JSON file > defaults.

Example
type Server struct {
	Host string `usage:"Server host"`
	Port int    `usage:"Server port"`
}

type Config struct {
	Timeout time.Duration `usage:"Request timeout"`
	Server  Server
}

cfg := Config{
	Timeout: 5 * time.Second,
	Server: Server{
		Host: "127.0.0.1",
		Port: 8080,
	},
}

_ = Load(&cfg,
	WithArgs([]string{"-server.port", "9090"}),
	WithoutImplicitConfigFile(),
	WithEnvLookup(func(string) (string, bool) { return "", false }),
)
Example (ApiService)
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,
}

_ = Load(&cfg)
Example (CliTool)
type Config struct {
	ConfigPath string `usage:"Path to config file"`
	Verbose    bool   `usage:"Enable verbose output"`
}

cfg := Config{}

_ = Load(&cfg,
	WithArgs([]string{"-verbose", "-configpath", "./dev.json"}),
	WithoutImplicitConfigFile(),
)
Example (WorkerService)
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,
	Queues:      []string{"emails", "billing"},
}

_ = Load(&cfg)

func Read

func Read(c interface{})

Read loads configuration and exits with status code 1 on error.

For library code, prefer Load so the caller can handle errors.

func ReadWithError added in v1.8.0

func ReadWithError(c interface{}) error

ReadWithError loads configuration and returns any error.

Types

type Option added in v1.8.0

type Option func(*Options)

Option customizes Load behaviour.

func WithArgs added in v1.8.0

func WithArgs(args []string) Option

WithArgs sets the command-line arguments used by Load.

func WithConfigFile added in v1.8.0

func WithConfigFile(filename string) Option

WithConfigFile sets the JSON file used by Load.

func WithConfigFlagName added in v1.8.0

func WithConfigFlagName(name string) Option

WithConfigFlagName changes the command-line flag used to point to a config file.

func WithEnvLookup added in v1.8.0

func WithEnvLookup(lookup func(string) (string, bool)) Option

WithEnvLookup sets a custom environment lookup function.

func WithImplicitConfigFile added in v1.8.0

func WithImplicitConfigFile(filename string) Option

WithImplicitConfigFile enables and sets the fallback JSON config filename.

func WithProgramName added in v1.8.0

func WithProgramName(name string) Option

WithProgramName sets the name used in generated help output.

func WithoutImplicitConfigFile added in v1.8.0

func WithoutImplicitConfigFile() Option

WithoutImplicitConfigFile disables automatic loading of config.json.

type Options added in v1.8.0

type Options struct {
	Args               []string
	ProgramName        string
	ConfigFile         string
	ConfigFlagName     string
	AutoConfigFile     bool
	AutoConfigFilename string
	EnvLookup          func(string) (string, bool)
}

Options controls how configuration is loaded.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL