SkillAgentSearch skills...

Config

📝 Go configuration manage(load,get,set,export). support JSON, YAML, TOML, Properties, INI, HCL, ENV and Flags. Multi file load, data override merge, parse ENV var. Go应用配置加载管理,支持多种格式,多文件加载,远程文件加载,支持数据合并,解析环境变量名

Install / Use

/learn @gookit/Config

README

Config

GitHub go.mod Go version Codacy Badge Build Status Actions Status Coverage Status Go Report Card Go Reference

config - Simple, full-featured Go application configuration management tool library.

中文说明

Features

  • Support multi format: JSON(default), JSON5, INI, Properties, YAML, TOML, ENV, Flags
    • JSON content support comments. will auto clear comments
    • HCL need to import github.com/hashicorp/hcl for custom driver
    • Other drivers are used on demand, not used will not be loaded into the application.
      • Possibility to add custom driver for your specific format
  • Support multi-file and multi-data loading
  • Support for loading configuration from system ENV
  • Support for loading configuration data from remote URLs
  • Support for setting configuration data from command line(flags)
  • Support listen and fire events on config data changed.
    • allow events: set.value, set.data, load.data, clean.data, reload.data
  • Support data overlay and merge, automatically load by key when loading multiple copies of data
  • Support for binding all or part of the configuration data to the structure
    • Support init default value by struct tag default:"def_value"
    • Support init default value from ENV default:"${APP_ENV | dev}"
  • Support get sub value by key-path, like map.key arr.2
  • Support parse ENV name and allow with default value. like envKey: ${SHELL|/bin/bash} -> envKey: /bin/zsh
  • Generic API: Get Int Uint Int64 Float String Bool Ints IntMap Strings StringMap ...
  • Complete unit test(code coverage > 95%)

Only use INI

If you just want to use INI for simple config management, recommended use gookit/ini

Load dotenv file

On gookit/ini: Provide a sub-package dotenv that supports importing data from files (eg .env) to ENV

go get github.com/gookit/ini/v2/dotenv

GoDoc

Install

go get github.com/gookit/config/v2

Usage

Here using the yaml format as an example(testdata/yml_other.yml):

name: app2
debug: false
baseKey: value2
shell: ${SHELL}
envKey1: ${NotExist|defValue}

map1:
    key: val2
    key2: val20

arr1:
    - val1
    - val21

Load data

examples code please see _examples/yaml.go:

package main

import (
    "github.com/gookit/config/v2"
    "github.com/gookit/config/v2/yaml"
)

// go run ./examples/yaml.go
func main() {
	// config.ParseEnv: will parse env var in string value. eg: shell: ${SHELL}
	config.WithOptions(config.ParseEnv)

	// add driver for support yaml content
	config.AddDriver(yaml.Driver)

	err := config.LoadFiles("testdata/yml_base.yml")
	if err != nil {
		panic(err)
	}

	// load more files
	err = config.LoadFiles("testdata/yml_other.yml")
	// can also load multi at once
	// err := config.LoadFiles("testdata/yml_base.yml", "testdata/yml_other.yml")
	if err != nil {
		panic(err)
	}

	// fmt.Printf("config data: \n %#v\n", config.Data())
}

Usage tips:

  • More extra options can be added using WithOptions(). For example: ParseEnv, ParseDefault
  • You can use AddDriver() to add the required format driver (json is loaded by default, no need to add)
  • The configuration data can then be loaded using LoadFiles() LoadStrings() etc.
    • You can pass in multiple files or call multiple times
    • Data loaded multiple times will be automatically merged by key

Bind Structure

Note: The default binding mapping tag of a structure is mapstructure, which can be changed by setting the decoder's option options.DecoderConfig.TagName

type User struct {
    Age  int  `mapstructure:"age"`
    Key  string `mapstructure:"key"`
    UserName  string `mapstructure:"user_name"`
    Tags []int  `mapstructure:"tags"`
}

user := User{}
err = config.BindStruct("user", &user)

fmt.Println(user.UserName) // inhere

Change struct tag name

config.WithOptions(func(opt *Options) {
    options.DecoderConfig.TagName = "config"
})

// use custom tag name.
type User struct {
  Age  int  `config:"age"`
  Key  string `config:"key"`
  UserName  string `config:"user_name"`
  Tags []int  `config:"tags"`
}

user := User{}
err = config.Decode(&user)

Can bind all config data to a struct:

config.Decode(&myConf)
// can also
config.BindStruct("", &myConf)

config.MapOnExists like BindStruct,but map binding only if key exists

Direct read data

  • Get integer
age := config.Int("age")
fmt.Print(age) // 100
  • Get bool
val := config.Bool("debug")
fmt.Print(val) // true
  • Get string
name := config.String("name")
fmt.Print(name) // inhere
  • Get strings(slice)
arr1 := config.Strings("arr1")
fmt.Printf("%#v", arr1) // []string{"val1", "val21"}
  • Get string map
val := config.StringMap("map1")
fmt.Printf("%#v",val) // map[string]string{"key":"val2", "key2":"val20"}
  • Value contains ENV var
value := config.String("shell")
fmt.Print(value) // "/bin/zsh"
  • Get value by key path
// from array
value := config.String("arr1.0")
fmt.Print(value) // "val1"

// from map
value := config.String("map1.key")
fmt.Print(value) // "val2"
  • Setting new value
// set value
config.Set("name", "new name")
name = config.String("name")
fmt.Print(name) // "new name"

Load from ENV

Support load ENV vars to config data.

  • Support set value to sub key in map.
    • eg: {"DB_USERNAME": "db.username"} value will set to username in db
// os env: APP_NAME=config APP_DEBUG=true DB_USERNAME=someone

// load ENV info
config.LoadOSEnvs(map[string]string{"APP_NAME": "app_name", "APP_DEBUG": "app_debug", "DB_USERNAME": "db.username"})

// read
config.Bool("app_debug") // true
config.String("app_name") // "config"

Load from flags

Support simple CLI flags parameter parsing, load to config data.

  • define format: name:type:desc OR name:type OR name:desc (type, desc is optional)
    • type can set flag type. allow: bool, int, string(default)
    • desc can set flag description
  • name can be in key path format.
    • eg: db.username, input: --db.username=someone values will be mapped to username of the db configuration
// 'debug' flag is bool type
config.LoadFlags([]string{"env", "debug:bool"})
// can with flag desc message
config.LoadFlags([]string{"env:set the run env"})
config.LoadFlags([]string{"debug:bool:set debug mode"})
// can set value to map key. eg: myapp --map1.sub-key=val
config.LoadFlags([]string{"map1.sub-key"})

Examples:

// flags like: --name inhere --env dev --age 99 --debug --map1.sub-key=val

// load flag info
keys := []string{
	"name",
	"env:set the run env",
	"age:int",
	"debug:bool:set debug mode",
	"map1.sub-key",
}
err := config.LoadFlags(keys)

// read
config.String("name") // "inhere"
config.String("env") // "dev"
config.Int("age") // 99
config.Bool("debug") // true
config.Get("map1") // map[string]any{"sub-key":"val"}

New config instance

You can create custom config instance

// create new instance, will auto register JSON driver
myConf := config.New("my-conf")

// create empty instance
myConf := config.NewEmpty("my-conf")

// create and with some options
myConf := config.NewWithOptions("my-conf", config.ParseEnv, config.ReadOnly)

Listen config change

Now, you can add a hook func for listen config data change. then, you can do something like: write data to file

Add hook func on create config:

hookFn := func(event string, c *Config) {
    fmt.Println("fire the:", event)
}

c := NewWithOptions("test", config.WithHookFunc(hookFn))
// for global config
config.WithOptions(config.WithHookFunc(hookFn))

After that, when calling LoadXXX, Set, SetData, ClearData methods, it will output:

fire the: load.data
fire the: set.value
fire the: set.data
fire the: clean.data

Watch loaded config files

To listen for changes to loaded config files, and reload the config when it changes, you need to use the https://github.com/fsnotify/fsnotify library. For usage, please refer to the example ./_example/watch_file.go

Also, you need to listen to the reload.data event:

config.WithOptions(config.WithHookFunc(func(event string, c *config.Config) {
    if event == config.OnReloadData {
        fmt.Println("config reloaded, you can do something ....")
    }
}))

When the configuration changes, you can do related things, for example: rebind the configuration to your struct.

Dump config data

Can use config.DumpTo() export the configuration data to the specified writer, such as: buffer,file

Dump to JSON file

buf := new(bytes.Buffer)

_, err := config.DumpTo(buf, config.JSON)
ioutil.WriteFile("my-config.json", buf.Bytes(), 0755)

Dump pretty JSON

You can set the default var JSONMarshalIndent or custom a new JSON driver.

config.JSONMarshalIndent = "    "
View on GitHub
GitHub Stars581
CategoryCustomer
Updated7d ago
Forks60

Languages

Go

Security Score

100/100

Audited on Mar 21, 2026

No findings