{"id":26455042,"url":"https://github.com/boolka/goconfig","last_synced_at":"2026-05-09T18:33:35.592Z","repository":{"id":282219607,"uuid":"947857840","full_name":"boolka/goconfig","owner":"boolka","description":"Go Application Configuration","archived":false,"fork":false,"pushed_at":"2026-03-18T20:14:19.000Z","size":99,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-19T08:34:33.067Z","etag":null,"topics":["config","configuration","deployment","go","goconfig","golang","json","json-config","json-configuration","properties","registry","settings","state","toml","toml-config","toml-configuration","yaml","yaml-config","yaml-configuration"],"latest_commit_sha":null,"homepage":"https://github.com/boolka/goconfig","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/boolka.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-13T11:04:16.000Z","updated_at":"2026-03-18T19:17:29.000Z","dependencies_parsed_at":"2025-04-17T10:03:31.298Z","dependency_job_id":"a73cd89c-d6c8-4369-93c5-6f019a3e687c","html_url":"https://github.com/boolka/goconfig","commit_stats":null,"previous_names":["boolka/goconfig"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/boolka/goconfig","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boolka%2Fgoconfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boolka%2Fgoconfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boolka%2Fgoconfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boolka%2Fgoconfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boolka","download_url":"https://codeload.github.com/boolka/goconfig/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boolka%2Fgoconfig/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32830920,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","configuration","deployment","go","goconfig","golang","json","json-config","json-configuration","properties","registry","settings","state","toml","toml-config","toml-configuration","yaml","yaml-config","yaml-configuration"],"created_at":"2025-03-18T20:29:46.164Z","updated_at":"2026-05-09T18:33:35.583Z","avatar_url":"https://github.com/boolka.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Configure your go applications with *goconfig*\n\n## The purpose\n\nThe main purpose of *goconfig* is to provide hierarchical configurations to go applications. It lets you define a set of default parameters, and extend them for different deployment environments (development, qa, staging, production, etc.) or external sources (vault).\n\nFor the library user, the idea is to treat the configuration directory as a \"black box\" and work with it as a whole, rather than using individual files.\n\n## Install\n\n```bash\ngo get github.com/boolka/goconfig@latest\n```\n\nUse `github.com/boolka/goconfig/pkg/config` package:\n- `New` function to create new config instance\n- `Options` struct to pass config options\n\n## Quick start\n\nCreate a `./config` directory and place configuration files in it, for example a `default.toml` file with the following contents:\n\n```toml\n[syslog-ng]\ndomain = 'syslog-ng'\nport = 601\n```\n\nThen create go file `cfg.go` to load appropriate configuration:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/boolka/goconfig\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\tcfg, _ := goconfig.New(ctx, goconfig.Options{})\n\n\tsyslogDomain := cfg.MustGet(ctx, \"syslog-ng.domain\")\n\tsyslogPort, _ := cfg.Get(ctx, \"syslog-ng.port\")\n\n\tfmt.Printf(\"%s:%d\", syslogDomain, syslogPort) // \"syslog-ng:601\"\n}\n```\n\nRun it:\n\n```bash\ngo run ./cfg.go\n```\n\nSuppose now we want to load environment variable. Create another configuration file in `./config` directory. Name it `env.toml` and copy the contents:\n\n```toml\n[syslog-ng]\ndomain = 'SYSLOG_NG_DOMAIN'\n```\n\nIn that case if \"SYSLOG_NG_DOMAIN\" environment contains non empty value, then it will be loaded when we call `cfg.Get(ctx, \"syslog-ng.domain\")`. Try it:\n\n```bash\nSYSLOG_NG_DOMAIN=custom-syslog-ng-domain go run ./cfg.go\n```\n\n## Deeper\n\n### API\n\n- `New(context.Context, config.Options) (*config.Config, error)`. Creates new config instance. Provide `config.Options` object to set config path and etc. If configuration directory is empty the `ErrEmptyDir` sentinel error will be returned.\n- `(*config.Config) Get(context.Context, path string, files ...string) (any, bool)`. Get method takes dot-delimited configuration path and returns a value if any. The last parameter specifies which files to search, with or without extension. If omitted, all files will be search through. The sequence of passed files does not change the search order. Second returned value states if it was found and follows comma ok idiom.\n- `(*config.Config) MustGet(context.Context, path string, files ...string) any`. MustGet method is the same as Get except that it panics if the path does not exist.\n\n#### Config options\n\nOptions specify configuration directory, instance, deployment, hostname and vault settings. All options are optional and can be omitted.\n\n```go\ngoconfig.Options{\n\tDirectory:         \"/path/to/directory\",       // trying to load from ./config by default\n\tFileSystem: \t   fs.ReadDirFS,               // useful in case of configuration embed\n\tInstance:          \"1\",\n\tDeployment:        \"production\",\n\tHostname:          \"localhost\",                // os.Hostname() by default\n\tLogger:            *slog.Logger,               // goconfig will remain silent when nil is received\n\tVaultClient:       any,                        // vault client instance\n}\n```\n\n##### Directory\n\nDirectory can be set by `Directory` option explicitly or implicitly via `GO_CONFIG_PATH` environment variable and must contain `.json`, `.yaml` (`.yml`) or `.toml` configuration files. All other files will be ignored. You can provide multiple directories delimited by `os.PathListSeparator`. Think of it as if you were putting all files together into one directory.\n\n##### FileSystem\n\nYou can specify `fs.ReadDirFS` interface to restrict file system access. Can be useful to embed configuration. If specified then `Directory` option is treated like path relative to `FileSystem`. Can be omitted.\n\n##### Deployment\n\nDeployment can be set by `Deployment` option explicitly or implicitly via `GO_DEPLOYMENT` environment variable. For example \"testing\", \"development\" or \"production\" is common used deployment types. There is no default value. So you need to provide it somehow. If it is omitted then all deployment configuration files will be ignored.\n\n##### Instance\n\nFor support multi instance configuration use `Instance` option. Can also be implicitly accepted via `GO_INSTANCE` environment variable. Instance value can only be a number. Meaning \"default-1.toml\" is valid instance file configuration, but \"custom-instance.toml\" is not.\n\nMulti instance configuration common usage is for get specific options for horizontal scaled multi pod environments. Suppose we have workers set \"worker-1\", \"worker-2\" ... \"worker-n\". By the multi instance configurations you can provide specific options for every single worker.\n\n##### Hostname\n\nIf you do not provide `Hostname` explicitly then `os.Hostname()` is called and the part after the first dot stripped off. For example suppose the `MacBook-Pro-5.local` is hostname. Then `Hostname` will borrow `MacBook-Pro-5`. It may be identical to the `hostname -s` call.\n\n`Hostname` must not contain dots in general. This is important for searching a specific value in the configuration, because the dot is a field separator. Choose to provide it explicitly when in doubt.\n\n##### Logger\n\nProduce output to supplied logger. Module will be silent if nil was received. Can be helpful for state some source errors. For example if vault was unavailable then logger will receive message describes whats going on.\n\n##### VaultClient\n\nTo use vault abilities you must use the `goconfig_vault` build tag and pass the vault client through the `VaultClient` option. Unauthorized client will lead to the runtime errors. For more details look at [Vault](####Vault) section below.\n\n### Configuration files\n\nApplication configuration is stored in `.json`, `.yaml` (`.yml`) or `.toml` files. Other files will be ignored. Special case is the `env.EXT` ([Environment](####Environment)) and `vault.EXT` ([Vault](####Vault)) files.\n\n#### Configuration files and field lookup order\n\nWhen looking up a value using the `Get` or `MustGet` method of a configuration, the sources(files) in the configuration directory(ies) are searched in the following order (from highest to lowest):\n\n- vault.EXT\n- env.EXT\n- local-{deployment}-{instance}.EXT\n- local-{deployment}.EXT\n- local-{instance}.EXT\n- local.EXT\n- {hostname}-{deployment}-{instance}.EXT\n- {hostname}-{deployment}.EXT\n- {hostname}-{instance}.EXT\n- {hostname}.EXT\n- {deployment}-{instance}.EXT\n- {deployment}.EXT\n- default-{instance}.EXT\n- default.EXT\n\nWhere:\n\n- EXT can be `.yaml` (`.yml`), `.json` or `.toml`\n- {instance} is an optional instance name string for multi-instance deployments\n- {hostname} is your hostname (don't use dots)\n- {deployment} is the deployment name\n- `env.EXT` and `vault.EXT` has special meanings and will be explained below\n\nIf you don't specify deployment, instance or hostname then the corresponding files will be ignored. All files with unknown filename signature will be treated as {deployment}.EXT and will be ignored if the deployment option is not provided. Dot prefixed files will be ignored.\n\n#### Local files\n\n`local.EXT`, `local-{deployment}-{instance}.EXT`, `local-{deployment}.EXT`, `local-{instance}.EXT` files are intended for use locally and to not be tracked in your version control system. Use it to overlap some definitions in local development for example.\n\n#### Environment\n\nThe `env.EXT` file contains environment variable names that will be mapped to your configuration structure. For example, the file `env.toml`:\n\n```toml\n[server]\nport = \"SERVER_PORT\"\n```\n\ndefines that we will try to load `SERVER_PORT` environment variable value into port configuration field. That means the expression\n\n```go\ncfg.MustGet(ctx, \"server.port\").(string) == os.Getenv(\"SERVER_PORT\")\n```\n\nwill match. Loading environment variables is dynamic. *goconfig* will not save values while the configuration module is initializing. That means that if the runtime changes environment variable while the application is running then this value will be loaded.\n\nEnvironment file may be any supported file extension - `.json`, `.yaml` (`.yml`) or `.toml`.\n\n#### Vault\n\nVault file will have special meaning only if you specify `goconfig_vault` build tag during compilation. Otherwise it would be treated as plain text file and field values loaded as they are.\n\nIf you create `vault.EXT` file then fields from that file will be looked up from the vault server. When *goconfig* instance is created then vault domain will be checked up.\n\nLoading vault variables is dynamic just like the environment variables. The field has special syntax `mount_path,secret_path,secret_key` where the vault secret mount path, secret path, and secret key separated by comma. Suppose we have a vault server with a configured postgresql secret and running at `http://localhost:8200`. Create directory `config` and place `vault.toml` file in to it with contents:\n\n```toml\n[postgresql]\nusername = \"secret,postgresql,username\"\npassword = \"secret,postgresql,password\"\n```\n\nThen create go file to upload keys:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/boolka/goconfig\"\n\tvaultApi \"github.com/hashicorp/vault/api\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tvaultCfg := vaultApi.DefaultConfig()\n\tvaultCfg.Address = \"http://localhost:8200\"\n\n\tclient, err := vaultApi.NewClient(vaultCfg)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tclient.SetToken(\"vault_token\")\n\n\tcfg, _ := goconfig.New(ctx, goconfig.Options{\n\t\tVaultClient: client,\n\t})\n\n\tusername := cfg.MustGet(ctx, \"postgresql.username\")\n\tpassword := cfg.MustGet(ctx, \"postgresql.password\")\n\n\tfmt.Printf(\"username: %s, password: %s\", username, password)\n}\n```\n\nIf you create correct vault secret with keys `username` and `password` and provide access then these values was printed.\n\nTo check that certain field available direct from vault source you need to specify files argument:\n\n```go\nif password, ok := cfg.Get(ctx, \"postgresql.password\", \"vault\"); ok {\n\t// available from vault source\n}\n```\n\nManaging vault auth methods, policies and secrets is out of scope.\n\n### Config embedding\n\nSuppose we want to embed configuration. We have `./config` directory containing our files. Embed the files first:\n\n```go\nimport \"embed\"\n\n//go:embed config/*\nvar configDir embed.FS\n```\n\nSpecify `FileSystem` option and corresponding `Directory`:\n\n```go\ncfg, err := goconfig.New(ctx, config.Options{\n\tFileSystem: \u0026configDir,\n\tDirectory:  \"config\",\n})\n```\n\nYou must specify `Directory` option explicitly when `FileSystem` is given even if the configuration files reside in the default `config` directory.\n\n## Cli usage\n\n*goconfig* can be used to load config fields in the terminal.\n\nFirst of all install it:\n\n```bash\ngo install github.com/boolka/goconfig/cmd/goconfig@latest\n```\n\nThen for example create directory `./config` and place `default.toml` file in to it with contents:\n\n```toml\ndelay = 1\n```\n\nExecute this example command:\n\n```bash\ngoconfig --get delay | xargs sleep\n```\n\nExecute `goconfig --help` for more info.\n\n## Under the hood\n\n*goconfig* loads configuration files at instance creation time. If the configuration has changed, you will need to create another instance to see them.\n\nThe following libraries are used to load concrete configuration files:\n\n- json: internal go library `encoding/json`\n- toml: `github.com/pelletier/go-toml/v2`\n- yaml: `gopkg.in/yaml.v3`\n\n*goconfig* handles a variety of number types that specific serialization libraries provide, by normalizing them. Type depends on number magnitude range:\n\n- x \u003c MinInt or x \u003e MaxUint: `float64`\n- x \u003e MaxInt and x \u003c= MaxUint: `uint`\n- x \u003e= MinInt and x \u003c= MaxInt: `int`\n\n## Links\n\n- Inspired with great library for node.js ecosystem [node-config](https://github.com/node-config/node-config)\n- [Vault](https://github.com/hashicorp/vault) api\n- [toml](https://github.com/pelletier/go-toml) format\n- [yaml](https://gopkg.in/yaml.v3) format\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboolka%2Fgoconfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboolka%2Fgoconfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboolka%2Fgoconfig/lists"}