config

package module
v0.0.0-...-a08c4ad Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: MIT Imports: 5 Imported by: 0

README

go-config

A Spring Boot style configuration loader for Go.

Automatically discovers configuration files, supports multiple formats, profiles, environment variable binding, remote configuration centers (etcd, Nacos, Consul, Apollo), and live reload.

Features

  • 🧩 Zero configuration – Just place config.yml in config/ or the current directory.
  • 🌍 Multiple profiles – Set APP_PROFILE=dev to load config-dev.yml.
  • 📁 Multi-format – YAML, TOML, JSON, XML, INI, Properties.
  • 🔄 Env overrideSERVER_PORT=9090 automatically overrides server.port.
  • Live reload – File watcher and remote config center push support.
  • 🔌 Extensible – Custom parsers and custom configuration sources via simple interfaces.
  • 🎯 Type-safe accessconfig.Get[int]("server.port") or struct binding.

Comparison with Other Libraries

Feature go-config Viper koanf configor
Auto file discovery ✅ (limited)
Profile support (dev/prod)
Env variable auto-binding ✅ (manual bind) ✅ (manual)
Live reload ❌ (requires extra) ❌ (requires extra)
Remote config (etcd / Nacos / Consul / Apollo) ✅ (built-in) ✅ (via providers) ✅ (via providers)
Type‑safe Get[T]
Multiple format support ✅ (6 formats) ✅ (5 formats) ✅ (6+ formats) ✅ (5 formats)
Zero‑code config center push
Simple API ⚠️ moderate ⚠️ moderate
  • ✅ = Built‑in, out of the box.
  • ⚠️ = Possible but requires manual setup.
  • ❌ = Not supported natively.

Why choose go-config?
It's the only Go library that combines Spring‑Boot‑style conventions, auto‑discovery, profiles, live reload, and built‑in support for etcd/Nacos — with a one‑liner API: config.LoadAndWatch(&cfg).

Installation

go get github.com/Junsy2025/go-config

Quick Start

  1. Create config/config.yml:
    server:
      port: 8080
    
  2. Load and use in your code:
    package main
    
    import (
        "fmt"
        "log"
    
        "github.com/Junsy2025/go-config"
    )
    
    type Config struct {
        Server struct {
            Port int `mapstructure:"port"`
        } `mapstructure:"server"`
    }
    
    func main() {
        var cfg Config
        if err := config.Load(&cfg); err != nil {
            log.Fatal(err)
        }
        fmt.Println(cfg.Server.Port)
    }
    

Profiles

Set the APP_PROFILE environment variable to switch profiles. The loader will first look for config-{profile}.{ext}, then fall back to config.{ext}.

Environment Variable Binding

All environment variables are automatically mapped to configuration keys. SERVER_PORT becomes server.port and overrides file values.

Supported Formats

Priority order: YAMLTOMLJSONXMLINIProperties

Custom Options

config.Load(&cfg,
    config.WithConfigDir("/etc/myapp"),   // specify config directory
    config.WithProfile("prod"),           // active profile
    config.WithParser(myCustomParser),    // register custom parser
)

Live Reload

Watch local file changes and automatically re-bind to your struct:

config.LoadAndWatch(&cfg)

// Optional callback on any update
config.OnChange(func(i interface{}) {
    c := i.(*Config)
    log.Println("Config updated, new port:", c.Server.Port)
})

To stop watching:

defer config.Stop()

Remote Configuration Sources

go-config provides built-in support for etcd, Nacos, Consul, and Apollo. All sources implement the same interface, so you can mix them freely — remote sources take precedence over the local file source (they are merged, and remote keys override local ones).

Every remote source requires:

  • a parser that matches the format of the configuration stored in the remote backend (e.g. &parser.YAMLParser{}, &parser.JSONParser{}).

  • to be added via config.WithSource(source).

  • the use of config.LoadAndWatch(&cfg, ...) to enable live reload.

etcd
import (
    "github.com/Junsy2025/go-config"
    "github.com/Junsy2025/go-config/parser"
    "github.com/Junsy2025/go-config/remote"
)

etcdSrc, err := remote.NewEtcdSource(
    []string{"127.0.0.1:2379"},   // etcd endpoints
    "/config/myapp.yaml",         // key path
    &parser.YAMLParser{},         // value format
)
if err != nil {
    log.Fatal(err)
}

var cfg AppConfig
if err := config.LoadAndWatch(&cfg, config.WithSource(etcdSrc)); err != nil {
    log.Fatal(err)
}

// Optional: react to updates
config.OnChange(func(i interface{}) {
    c := i.(*AppConfig)
    log.Println("Config changed:", c.Server.Port)
})
Nacos
nacosSrc, err := remote.NewNacosSource(
    "127.0.0.1:8848",            // server address
    "",                          // namespace ID (empty = public)
    "myapp.yaml",               // Data ID
    "DEFAULT_GROUP",            // Group
    &parser.YAMLParser{},       // value format
)
if err != nil {
    log.Fatal(err)
}

config.LoadAndWatch(&cfg, config.WithSource(nacosSrc))
Consul
consulSrc, err := remote.NewConsulSource(
    "127.0.0.1:8500",           // agent address
    "config/myapp.yaml",        // KV path
    &parser.YAMLParser{},       // value format
)
if err != nil {
    log.Fatal(err)
}

config.LoadAndWatch(&cfg, config.WithSource(consulSrc))
Apollo
apolloSrc, err := remote.NewApolloSource(
    "myApp",                    // AppId
    "default",                  // Cluster
    "application",              // Namespace (e.g., "application", "myapp.yaml")
    "http://localhost:8080",    // Meta server URL
    &parser.YAMLParser{},       // value format
)
if err != nil {
    log.Fatal(err)
}

config.LoadAndWatch(&cfg, config.WithSource(apolloSrc))

Custom Source

Implement the loader.Source interface to connect any backend:

type Source interface {
    Load(ctx context.Context) (map[string]interface{}, error)
    Watch(ctx context.Context, onChange func(map[string]interface{})) error
    Name() string
}

// Usage
config.LoadAndWatch(&cfg, config.WithSource(myCustomSource))

Type-Safe Global Access

You can also read values without passing a struct:

port := config.Get[int]("server.port")
dbHost := config.Get[string]("database.host")

This reads directly from the live configuration (including updates).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Get

func Get[T any](key string) T

Get returns a typed value from the global configuration using a dot‑separated key.

func Load

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

Load reads configuration from all registered sources and binds it to cfg.

func LoadAndWatch

func LoadAndWatch(cfg interface{}, opts ...loader.Option) error

LoadAndWatch loads configuration and starts watching for changes. Changes are automatically re-bound to the struct passed in cfg.

func MustLoad

func MustLoad(cfg interface{}, opts ...loader.Option)

MustLoad is like Load but panics if an error occurs.

func OnChange

func OnChange(fn func(cfg interface{}))

OnChange registers a callback that fires after any configuration change.

func Stop

func Stop()

Stop stops all configuration watches and releases resources.

func WithConfigDir

func WithConfigDir(dir string) loader.Option

WithConfigDir sets the base directory for configuration files.

func WithParser

func WithParser(p parser.Parser) loader.Option

WithParser adds a custom parser for file sources.

func WithProfile

func WithProfile(profile string) loader.Option

WithProfile sets the active profile (e.g., "dev", "prod").

func WithSource

func WithSource(s loader.Source) loader.Option

WithSource adds a configuration source (e.g., remote config center). Sources added later have higher priority during merging.

Types

This section is empty.

Directories

Path Synopsis
examples
file_basic command
nacos command

Jump to

Keyboard shortcuts

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