{"id":13411052,"url":"https://github.com/gookit/config","last_synced_at":"2025-05-16T00:06:48.310Z","repository":{"id":37336299,"uuid":"140065565","full_name":"gookit/config","owner":"gookit","description":"📝 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应用配置加载管理，支持多种格式，多文件加载，远程文件加载，支持数据合并，解析环境变量名","archived":false,"fork":false,"pushed_at":"2025-04-25T11:23:15.000Z","size":694,"stargazers_count":550,"open_issues_count":10,"forks_count":56,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-25T12:29:13.311Z","etag":null,"topics":["config","config-management","configuration","configuration-management","flags","goconfig","gookit","hcl","ini","json","properties","toml","yaml"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/gookit/config/v2","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gookit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-07-07T08:11:39.000Z","updated_at":"2025-04-25T11:23:19.000Z","dependencies_parsed_at":"2023-02-18T00:31:48.052Z","dependency_job_id":"b3fcf799-6ce5-4550-a396-f1eaafca387c","html_url":"https://github.com/gookit/config","commit_stats":{"total_commits":325,"total_committers":13,"mean_commits":25.0,"dds":0.3046153846153846,"last_synced_commit":"365c527c2fa86295731ecc7c9dc138dfc4d8c670"},"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Fconfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Fconfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Fconfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Fconfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gookit","download_url":"https://codeload.github.com/gookit/config/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254442854,"owners_count":22071878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["config","config-management","configuration","configuration-management","flags","goconfig","gookit","hcl","ini","json","properties","toml","yaml"],"created_at":"2024-07-30T20:01:11.111Z","updated_at":"2025-05-16T00:06:48.297Z","avatar_url":"https://github.com/gookit.png","language":"Go","readme":"# Config\n\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/gookit/config?style=flat-square)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/1e0f0ca096d94ffdab375234ec4167ee)](https://app.codacy.com/gh/gookit/config?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=gookit/config\u0026utm_campaign=Badge_Grade_Settings)\n[![Build Status](https://travis-ci.org/gookit/config.svg?branch=master)](https://travis-ci.org/gookit/config)\n[![Actions Status](https://github.com/gookit/config/workflows/Unit-Tests/badge.svg)](https://github.com/gookit/config/actions)\n[![Coverage Status](https://coveralls.io/repos/github/gookit/config/badge.svg?branch=master)](https://coveralls.io/github/gookit/config?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/gookit/config)](https://goreportcard.com/report/github.com/gookit/config)\n[![Go Reference](https://pkg.go.dev/badge/github.com/gookit/config/v2.svg)](https://pkg.go.dev/github.com/gookit/config/v2)\n\n`config` - Simple, full-featured Go application configuration management tool library.\n\n\u003e **[中文说明](README.zh-CN.md)**\n\n## Features\n\n- Support multi format: `JSON`(default), `JSON5`, `INI`, `Properties`, `YAML`, `TOML`, `HCL`, `ENV`, `Flags`\n  - `JSON` content support comments. will auto clear comments\n  - Other drivers are used on demand, not used will not be loaded into the application.\n    - Possibility to add custom driver for your specific format\n- Support multi-file and multi-data loading\n- Support for loading configuration from system ENV\n- Support for loading configuration data from remote URLs\n- Support for setting configuration data from command line(`flags`)\n- Support listen and fire events on config data changed. \n  - allow events: `set.value`, `set.data`, `load.data`, `clean.data`, `reload.data`\n- Support data overlay and merge, automatically load by key when loading multiple copies of data\n- Support for binding all or part of the configuration data to the structure\n  - Support init default value by struct tag `default:\"def_value\"`\n  - Support init default value from ENV `default:\"${APP_ENV | dev}\"`\n- Support get sub value by key-path, like `map.key` `arr.2`\n- Support parse ENV name and allow with default value. like `envKey: ${SHELL|/bin/bash}` -\u003e `envKey: /bin/zsh`\n- Generic API: `Get` `Int` `Uint` `Int64` `Float` `String` `Bool` `Ints` `IntMap` `Strings` `StringMap` ...\n- Complete unit test(code coverage \u003e 95%)\n\n## Only use INI\n\nIf you just want to use INI for simple config management, recommended use [gookit/ini](https://github.com/gookit/ini)\n\n### Load dotenv file\n\nOn `gookit/ini`:  Provide a sub-package `dotenv` that supports importing data from files (eg `.env`) to ENV\n\n```shell\ngo get github.com/gookit/ini/v2/dotenv\n```\n\n## GoDoc\n\n- [godoc for github](https://pkg.go.dev/github.com/gookit/config)\n\n## Install\n\n```bash\ngo get github.com/gookit/config/v2\n```\n\n## Usage\n\nHere using the yaml format as an example(`testdata/yml_other.yml`):\n\n```yaml\nname: app2\ndebug: false\nbaseKey: value2\nshell: ${SHELL}\nenvKey1: ${NotExist|defValue}\n\nmap1:\n    key: val2\n    key2: val20\n\narr1:\n    - val1\n    - val21\n```\n\n### Load data\n\n\u003e examples code please see [_examples/yaml.go](_examples/yaml.go):\n\n```go\npackage main\n\nimport (\n    \"github.com/gookit/config/v2\"\n    \"github.com/gookit/config/v2/yaml\"\n)\n\n// go run ./examples/yaml.go\nfunc main() {\n\t// config.ParseEnv: will parse env var in string value. eg: shell: ${SHELL}\n\tconfig.WithOptions(config.ParseEnv)\n\n\t// add driver for support yaml content\n\tconfig.AddDriver(yaml.Driver)\n\n\terr := config.LoadFiles(\"testdata/yml_base.yml\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// load more files\n\terr = config.LoadFiles(\"testdata/yml_other.yml\")\n\t// can also load multi at once\n\t// err := config.LoadFiles(\"testdata/yml_base.yml\", \"testdata/yml_other.yml\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// fmt.Printf(\"config data: \\n %#v\\n\", config.Data())\n}\n```\n**Usage tips**:\n\n- More extra options can be added using `WithOptions()`. For example: `ParseEnv`, `ParseDefault`\n- You can use `AddDriver()` to add the required format driver (`json` is loaded by default, no need to add)\n- The configuration data can then be loaded using `LoadFiles()` `LoadStrings()` etc.\n  - You can pass in multiple files or call multiple times\n  - Data loaded multiple times will be automatically merged by key\n\n## Bind Structure\n\n\u003e Note: The default binding mapping tag of a structure is `mapstructure`, which can be changed by setting the decoder's option `options.DecoderConfig.TagName`\n\n```go\ntype User struct {\n    Age  int  `mapstructure:\"age\"`\n    Key  string `mapstructure:\"key\"`\n    UserName  string `mapstructure:\"user_name\"`\n    Tags []int  `mapstructure:\"tags\"`\n}\n\nuser := User{}\nerr = config.BindStruct(\"user\", \u0026user)\n\nfmt.Println(user.UserName) // inhere\n```\n\n**Change struct tag name**\n\n```go\nconfig.WithOptions(func(opt *Options) {\n    options.DecoderConfig.TagName = \"config\"\n})\n\n// use custom tag name.\ntype User struct {\n  Age  int  `config:\"age\"`\n  Key  string `config:\"key\"`\n  UserName  string `config:\"user_name\"`\n  Tags []int  `config:\"tags\"`\n}\n\nuser := User{}\nerr = config.Decode(\u0026user)\n```\n\n**Can bind all config data to a struct**:\n\n```go\nconfig.Decode(\u0026myConf)\n// can also\nconfig.BindStruct(\"\", \u0026myConf)\n```\n\n\u003e `config.MapOnExists` like `BindStruct`，but map binding only if key exists\n\n### Direct read data\n\n- Get integer\n\n```go\nage := config.Int(\"age\")\nfmt.Print(age) // 100\n```\n\n- Get bool\n\n```go\nval := config.Bool(\"debug\")\nfmt.Print(val) // true\n```\n\n- Get string\n\n```go\nname := config.String(\"name\")\nfmt.Print(name) // inhere\n```\n\n- Get strings(slice)\n\n```go\narr1 := config.Strings(\"arr1\")\nfmt.Printf(\"%#v\", arr1) // []string{\"val1\", \"val21\"}\n```\n\n- Get string map\n\n```go\nval := config.StringMap(\"map1\")\nfmt.Printf(\"%#v\",val) // map[string]string{\"key\":\"val2\", \"key2\":\"val20\"}\n```\n\n- Value contains ENV var\n\n```go\nvalue := config.String(\"shell\")\nfmt.Print(value) // \"/bin/zsh\"\n```\n\n- Get value by key path\n\n```go\n// from array\nvalue := config.String(\"arr1.0\")\nfmt.Print(value) // \"val1\"\n\n// from map\nvalue := config.String(\"map1.key\")\nfmt.Print(value) // \"val2\"\n```\n\n- Setting new value\n\n```go\n// set value\nconfig.Set(\"name\", \"new name\")\nname = config.String(\"name\")\nfmt.Print(name) // \"new name\"\n```\n\n## Load from ENV\n\nSupport load ENV vars to config data.\n\n- Support set value to sub key in map.\n  - eg: `{\"DB_USERNAME\": \"db.username\"}` value will set to `username` in `db`\n\n```go\n// os env: APP_NAME=config APP_DEBUG=true DB_USERNAME=someone\n\n// load ENV info\nconfig.LoadOSEnvs(map[string]string{\"APP_NAME\": \"app_name\", \"APP_DEBUG\": \"app_debug\", \"DB_USERNAME\": \"db.username\"})\n\n// read\nconfig.Bool(\"app_debug\") // true\nconfig.String(\"app_name\") // \"config\"\n```\n\n## Load from flags\n\nSupport simple CLI flags parameter parsing, load to config data.\n\n- define format: `name:type:desc` OR `name:type` OR `name:desc` (type, desc is optional)\n  - `type` can set `flag` type. allow: `bool`, `int`, `string`(default)\n  - `desc` can set `flag` description\n- `name` can be in key path format. \n  - eg: `db.username`, input: `--db.username=someone` values will be mapped to `username` of the `db` configuration\n\n```go\n// 'debug' flag is bool type\nconfig.LoadFlags([]string{\"env\", \"debug:bool\"})\n// can with flag desc message\nconfig.LoadFlags([]string{\"env:set the run env\"})\nconfig.LoadFlags([]string{\"debug:bool:set debug mode\"})\n// can set value to map key. eg: myapp --map1.sub-key=val\nconfig.LoadFlags([]string{\"map1.sub-key\"})\n```\n\nExamples:\n\n```go\n// flags like: --name inhere --env dev --age 99 --debug --map1.sub-key=val\n\n// load flag info\nkeys := []string{\n\t\"name\",\n\t\"env:set the run env\",\n\t\"age:int\",\n\t\"debug:bool:set debug mode\",\n\t\"map1.sub-key\",\n}\nerr := config.LoadFlags(keys)\n\n// read\nconfig.String(\"name\") // \"inhere\"\nconfig.String(\"env\") // \"dev\"\nconfig.Int(\"age\") // 99\nconfig.Bool(\"debug\") // true\nconfig.Get(\"map1\") // map[string]any{\"sub-key\":\"val\"}\n```\n\n## New config instance\n\nYou can create custom config instance\n\n```go\n// create new instance, will auto register JSON driver\nmyConf := config.New(\"my-conf\")\n\n// create empty instance\nmyConf := config.NewEmpty(\"my-conf\")\n\n// create and with some options\nmyConf := config.NewWithOptions(\"my-conf\", config.ParseEnv, config.ReadOnly)\n```\n\n## Listen config change\n\nNow, you can add a hook func for listen config data change. then, you can do something like: write data to file\n\n**Add hook func on create config**:\n\n```go\nhookFn := func(event string, c *Config) {\n    fmt.Println(\"fire the:\", event)\n}\n\nc := NewWithOptions(\"test\", config.WithHookFunc(hookFn))\n// for global config\nconfig.WithOptions(config.WithHookFunc(hookFn))\n```\n\nAfter that, when calling `LoadXXX, Set, SetData, ClearData` methods, it will output:\n\n```text\nfire the: load.data\nfire the: set.value\nfire the: set.data\nfire the: clean.data\n```\n\n### Watch loaded config files\n\nTo 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. \nFor usage, please refer to the example [./_example/watch_file.go](_examples/watch_file.go)\n\nAlso, you need to listen to the `reload.data` event:\n\n```go\nconfig.WithOptions(config.WithHookFunc(func(event string, c *config.Config) {\n    if event == config.OnReloadData {\n        fmt.Println(\"config reloaded, you can do something ....\")\n    }\n}))\n```\n\nWhen the configuration changes, you can do related things, for example: rebind the configuration to your struct.\n\n## Dump config data\n\n\u003e Can use `config.DumpTo()` export the configuration data to the specified `writer`, such as: buffer,file\n\n**Dump to JSON file**\n\n```go\nbuf := new(bytes.Buffer)\n\n_, err := config.DumpTo(buf, config.JSON)\nioutil.WriteFile(\"my-config.json\", buf.Bytes(), 0755)\n```\n\n**Dump pretty JSON**\n\nYou can set the default var `JSONMarshalIndent` or custom a new JSON driver. \n\n```go\nconfig.JSONMarshalIndent = \"    \"\n```\n\n**Dump to YAML file**\n\n```go\n_, err := config.DumpTo(buf, config.YAML)\nioutil.WriteFile(\"my-config.yaml\", buf.Bytes(), 0755)\n```\n\n## Available options\n\n```go\n// Options config options\ntype Options struct {\n\t// parse env in string value. like: \"${EnvName}\" \"${EnvName|default}\"\n\tParseEnv bool\n    // ParseTime parses a duration string to time.Duration\n    // eg: 10s, 2m\n    ParseTime bool\n\t// config is readonly. default is False\n\tReadonly bool\n\t// enable config data cache. default is False\n\tEnableCache bool\n\t// parse key, allow find value by key path. default is True eg: 'key.sub' will find `map[key]sub`\n\tParseKey bool\n\t// the delimiter char for split key path, if `FindByPath=true`. default is '.'\n\tDelimiter byte\n\t// default write format\n\tDumpFormat string\n\t// default input format\n\tReadFormat string\n\t// DecoderConfig setting for binding data to struct\n\tDecoderConfig *mapstructure.DecoderConfig\n\t// HookFunc on data changed.\n\tHookFunc HookFunc\n\t// ParseDefault tag on binding data to struct. tag: default\n\tParseDefault bool\n}\n```\n\n\u003e **TIP**: please visit https://pkg.go.dev/github.com/gookit/config/v2#Options to see the latest options information\n\nExamples for set options:\n\n```go\nconfig.WithOptions(config.WithTagName(\"mytag\"))\nconfig.WithOptions(func(opt *Options) {\n    opt.SetTagNames(\"config\")\n})\n```\n\n### Options: Parse default\n\nSupport parse default value by struct tag `default`, and support parse sub struct.\n\n\u003e **NOTE**⚠️ If you want to parse a substruct, you need to set the `default:\"\"` flag on the struct, \n\u003e otherwise the fields that will not resolve to it will not be resolved.\n\n```go\n// add option: config.ParseDefault\nc := config.New(\"test\").WithOptions(config.ParseDefault)\n\n// only set name\nc.SetData(map[string]any{\n    \"name\": \"inhere\",\n})\n\n// age load from default tag\ntype User struct {\n    Age  int `default:\"30\"`\n    Name string\n    Tags []int\n}\n\nuser := \u0026User{}\ngoutil.MustOk(c.Decode(user))\ndump.Println(user)\n```\n\n**Output**:\n\n```shell\n\u0026config_test.User {\n  Age: int(30),\n  Name: string(\"inhere\"), #len=6\n  Tags: []int [ #len=0\n  ],\n},\n```\n\n## API Methods Refer\n\n### Load Config\n\n- `LoadOSEnvs(nameToKeyMap map[string]string)` Load data from os ENV\n- `LoadData(dataSource ...any) (err error)` Load from struts or maps\n- `LoadFlags(keys []string) (err error)` Load from CLI flags\n- `LoadExists(sourceFiles ...string) (err error)` \n- `LoadFiles(sourceFiles ...string) (err error)`\n- `LoadFromDir(dirPath, format string) (err error)` Load custom format files from the given directory, the file name will be used as the key\n- `LoadRemote(format, url string) (err error)`\n- `LoadSources(format string, src []byte, more ...[]byte) (err error)`\n- `LoadStrings(format string, str string, more ...string) (err error)`\n- `LoadFilesByFormat(format string, sourceFiles ...string) (err error)`\n- `LoadExistsByFormat(format string, sourceFiles ...string) error`\n\n### Getting Values\n\n- `Bool(key string, defVal ...bool) bool`\n- `Int(key string, defVal ...int) int`\n- `Uint(key string, defVal ...uint) uint`\n- `Int64(key string, defVal ...int64) int64`\n- `Ints(key string) (arr []int)`\n- `IntMap(key string) (mp map[string]int)`\n- `Float(key string, defVal ...float64) float64`\n- `String(key string, defVal ...string) string`\n- `Strings(key string) (arr []string)`\n- `SubDataMap(key string) maputi.Data`\n- `StringMap(key string) (mp map[string]string)`\n- `Get(key string, findByPath ...bool) (value any)`\n\n**Mapping data to struct:**\n\n- `Decode(dst any) error`\n- `BindStruct(key string, dst any) error`\n- `MapOnExists(key string, dst any) error`\n\n### Setting Values\n\n- `Set(key string, val any, setByPath ...bool) (err error)`\n\n### Useful Methods\n\n- `Getenv(name string, defVal ...string) (val string)`\n- `AddDriver(driver Driver)`\n- `Data() map[string]any`\n- `SetData(data map[string]any)` set data to override the Config.Data\n- `Exists(key string, findByPath ...bool) bool`\n- `DumpTo(out io.Writer, format string) (n int64, err error)`\n\n## Run Tests\n\n```bash\ngo test -cover\n// contains all sub-folder\ngo test -cover ./...\n```\n\n## Projects using config\n\nCheck out these projects, which use https://github.com/gookit/config :\n\n- https://github.com/JanDeDobbeleer/oh-my-posh A prompt theme engine for any shell.\n- [+ See More](https://pkg.go.dev/github.com/gookit/config?tab=importedby)\n\n## Gookit packages\n\n- [gookit/ini](https://github.com/gookit/ini) Go config management, use INI files\n- [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP \n- [gookit/gcli](https://github.com/gookit/gcli) build CLI application, tool library, running CLI commands\n- [gookit/event](https://github.com/gookit/event) Lightweight event manager and dispatcher implements by Go\n- [gookit/cache](https://github.com/gookit/cache) Generic cache use and cache manager for golang. support File, Memory, Redis, Memcached.\n- [gookit/config](https://github.com/gookit/config) Go config management. support JSON, YAML, TOML, INI, HCL, ENV and Flags\n- [gookit/color](https://github.com/gookit/color) A command-line color library with true color support, universal API methods and Windows support\n- [gookit/filter](https://github.com/gookit/filter) Provide filtering, sanitizing, and conversion of golang data\n- [gookit/validate](https://github.com/gookit/validate) Use for data validation and filtering. support Map, Struct, Form data\n- [gookit/goutil](https://github.com/gookit/goutil) Some utils for the Go: string, array/slice, map, format, cli, env, filesystem, test and more\n- More, please see https://github.com/gookit\n\n## See also\n\n- Ini parser [gookit/ini/parser](https://github.com/gookit/ini/tree/master/parser)\n- Properties parser [gookit/properties](https://github.com/gookit/properties)\n- Json5 parser\n  - [yosuke-furukawa/json5](https://github.com/yosuke-furukawa/json5)\n  - [titanous/json5](https://github.com/titanous/json5)\n- Json parser\n  - [goccy/go-json](https://github.com/goccy/go-json)\n  - [json-iterator/go](https://github.com/json-iterator/go)\n- Yaml parser\n  - [goccy/go-yaml](https://github.com/goccy/go-yaml)\n  - [go-yaml/yaml](https://github.com/go-yaml/yaml)\n- Toml parser [go toml](https://github.com/BurntSushi/toml)\n- Data merge [mergo](https://github.com/imdario/mergo)\n- Map structure [mapstructure](https://github.com/mitchellh/mapstructure)\n\n## License\n\n**MIT**\n","funding_links":[],"categories":["配置","Config managers","Configuration","配置管理 `配置解析库`","配置管理","Uncategorized"],"sub_categories":["标准CLI","Standard CLI","Advanced Console UIs","标准 CLI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgookit%2Fconfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgookit%2Fconfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgookit%2Fconfig/lists"}