{"id":13411130,"url":"https://github.com/nil-go/konf","last_synced_at":"2025-04-12T14:58:13.449Z","repository":{"id":142258320,"uuid":"609983880","full_name":"nil-go/konf","owner":"nil-go","description":"The simplest config loader for Go that reads/watches from file, env, flag and clouds (AWS, Azure, GCP). ","archived":false,"fork":false,"pushed_at":"2025-04-07T14:27:28.000Z","size":1843,"stargazers_count":313,"open_issues_count":0,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T14:58:04.935Z","etag":null,"topics":["appconfig","aws","azure","config","config-loader","configuration","configuration-file","configuration-loader","environment-variables","flags","gcp","go","golang","minimalist","pflag"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/nil-go/konf","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/nil-go.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}},"created_at":"2023-03-05T20:08:17.000Z","updated_at":"2025-04-09T09:20:15.000Z","dependencies_parsed_at":"2023-12-19T01:01:13.634Z","dependency_job_id":"2c6abd37-e1f4-452b-b286-2525dd1c8fdf","html_url":"https://github.com/nil-go/konf","commit_stats":{"total_commits":523,"total_committers":6,"mean_commits":87.16666666666667,"dds":0.4780114722753346,"last_synced_commit":"6d5415e5583e7cd76cf90acd8b5ac2e240a359d6"},"previous_names":["nil-go/konf","ktong/konf"],"tags_count":191,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nil-go%2Fkonf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nil-go%2Fkonf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nil-go%2Fkonf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nil-go%2Fkonf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nil-go","download_url":"https://codeload.github.com/nil-go/konf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248586250,"owners_count":21128997,"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":["appconfig","aws","azure","config","config-loader","configuration","configuration-file","configuration-loader","environment-variables","flags","gcp","go","golang","minimalist","pflag"],"created_at":"2024-07-30T20:01:11.617Z","updated_at":"2025-04-12T14:58:13.420Z","avatar_url":"https://github.com/nil-go.png","language":"Go","readme":"# The simplest config loader for Go\n\n![Go Version](https://img.shields.io/github/go-mod/go-version/nil-go/konf)\n[![Go Reference](https://pkg.go.dev/badge/github.com/nil-go/konf.svg)](https://pkg.go.dev/github.com/nil-go/konf)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nil-go/konf)](https://goreportcard.com/report/github.com/nil-go/konf)\n[![Build](https://github.com/nil-go/konf/actions/workflows/test.yml/badge.svg)](https://github.com/nil-go/konf/actions/workflows/test.yml)\n[![Coverage](https://codecov.io/gh/nil-go/konf/branch/main/graph/badge.svg)](https://codecov.io/gh/nil-go/konf)\n\nkonf offers an(other) opinion on how Go programs can read configuration without\nbecoming coupled to a particular configuration source.\n\n## Features\n\n- [konf.Unmarshal](#usage) for reading configuration to any type of object.\n- [konf.OnChange](#usage) for registering callbacks while configuration changes.\n- [konf.Explain](#understand-the-configuration) for understanding where the configuration is loaded from.\n- [Various providers](#configuration-providers) for loading configuration from major clouds,\n  [AWS](examples/aws), [Azure](examples/azure), and [GCP](examples/gcp) with [Notifier](notifier) for notifying the\n  changes of configuration.\n- [Zero dependencies](go.mod) in core module which supports loading configuration\n  from environment variables,flags, and embed file system.\n\n## Benchmarks\n\nThe following [benchmarks](benchmark)  compare the performance of konf\nwith [spf13/viper](https://github.com/spf13/viper) and\n[knadh/koanf](https://github.com/knadh/koanf), which are inspiration of konf.\n\n|       | Unmarshal (ns/op) | Unmarshal (allocs/op) | Get[^1] (ns/op) | Get (allocs/op) |\n|:------|------------------:|----------------------:|----------------:|----------------:|\n| Konf  |         __41.09__ |                 __4__ |           16.71 |           __1__ |\n| Viper |             614.8 |                    22 |           104.9 |               3 |\n| Koanf |             15949 |                   657 |       __7.898__ |           __1__ |\n\n[^1]: Comparing to Get in both Viper and Koanf only can get the primitive types, Get in Konf can get any type\nsince it's just a wrapper of Unmarshal. So for complex struct, it only needs single Konf Get\nbut may needs multiple Get(s) in Viper and Koanf.\n\n## Usage\n\nSomewhere, early in an application's life, it will make a decision about which\nconfiguration source(s) (implementation) it actually wants to use. Something like:\n\n```go\n//go:embed config\nvar config embed.FS\n\nfunc main() {\n    var config konf.Config\n\n    // Load configuration from embed file system.\n    if err := config.Load(fs.New(config, \"config/config.json\")); err != nil {\n        // Handle error here.\n    }\n    // Load configuration from environment variables.\n    if err := config.Load(env.New(env.WithPrefix(\"server\"))); err != nil {\n        // Handle error here.\n    }\n\n    // Watch the changes of configuration.\n    go func() {\n      if err := config.Watch(ctx); err != nil {\n        // Handle error here.\n      }\n    }()\n\n    konf.SetDefault(config)\n\n    // ... other setup code ...\n}\n```\n\nOutside of this early setup, no other packages need to know about the choice of\nconfiguration source(s). They read configuration in terms of functions in package `konf`:\n\n```go\nfunc (app *appObject) Run() {\n    // Server configuration with default values.\n    serverConfig := struct {\n        Host string\n        Port int\n    }{\n        Host: \"localhost\",\n        Port: \"8080\",\n    }\n    // Read the server configuration.\n    if err := konf.Unmarshal(\"server\", \u0026serverConfig);  err != nil {\n        // Handle error here.\n    }\n\n    // Register callbacks while server configuration changes.\n    konf.OnChange(func() {\n      // Reconfig the application object.\n    }, \"server\")\n\n    // ... use cfg in app code ...\n}\n```\n\n## Design\n\nIt contains two APIs with two different sets of users:\n\n- The `Config` type is intended for application authors. It provides a relatively\n  small API which can be used everywhere you want to read configuration.\n  It defers the actual configuration loading to the `Loader` interface.\n- The `Loader` and `Watcher` interface is intended for configuration source library implementers.\n  They are pure interfaces which can be implemented to provide the actual configuration.\n\nThis decoupling allows application developers to write code in terms of `*konf.Config`\nwhile the configuration source(s) is managed \"up stack\" (e.g. in or near `main()`).\nApplication developers can then switch configuration sources(s) as necessary.\n\n## Change Notification\n\nThe providers for loading configuration from clouds periodically poll the configuration source.\nIt also supports watching the changes of configuration using corresponding notifier.\nFor example, the `sns` notifier notifies the changes of `appconfig`  and `s3` provider:\n\n```go\nnotifier := sns.NewNotifier(\"konf-test\")\nnotifier.Register(s3Loader, appConfigLoader)\ngo func() {\n  if err := notifier.Start(ctx); err != nil {\n    // handle error\n  }\n}()\n```\n\n## Understand the configuration\n\nWhile the configuration is loaded from multiple sources, static like environments or dynamic like AWS AppConfig,\nit's hard to understand where a final value comes from. The `Config.Explain` method provides information\nabout how Config resolve each value from loaders for the given path. One example explanation is like:\n\n```\nconfig.nest has value [map] is loaded by map.\nHere are other value(loader)s:\n  - env(env)\n```\n\nEven more, the `Config.Explain` blurs sensitive information (e.g. password, secret, api keys).\n\n## Observability\n\nFor watching the changes of configuration, it uses `slog.Default()` for logging. You can change the logger\nvia option `konf.WithLogHandler`. Furthermore, you also can register onStatus via option `konf.WithOnStatus`\nto monitor the status of configuration loading/watching, e.g. recording metrics.\n\n## Configuration Providers\n\nThere are providers for the following configuration sources.\n\n| Loader                                      | Load From                                                                                                               | Watch Changes | Notifier                              |\n|:--------------------------------------------|:------------------------------------------------------------------------------------------------------------------------|:-------------:|:--------------------------------------|\n| [`env`](provider/env)                       | environment variables                                                                                                   |               |                                       |\n| [`fs`](provider/fs)                         | [fs.FS](https://pkg.go.dev/io/fs)                                                                                       |               |                                       |\n| [`file`](provider/file)                     | file                                                                                                                    |       ✓       |                                       |\n| [`flag`](provider/flag)                     | [flag](https://pkg.go.dev/flag)                                                                                         |               |                                       |\n| [`pflag`](provider/pflag)                   | [spf13/pflag](https://github.com/spf13/pflag)                                                                           |               |                                       |\n| [`appconfig`](provider/appconfig)           | [AWS AppConfig](https://aws.amazon.com/systems-manager/features/appconfig/)                                             |       ✓       | [sns](notifier/sns)                   |\n| [`s3`](provider/s3)                         | [AWS S3](https://aws.amazon.com/s3)                                                                                     |       ✓       | [sns](notifier/sns)                   |\n| [`parameterstore`](provider/parameterstore) | [AWS ParameterStore](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) |       ✓       | [sns](notifier/sns)                   |\n| [`azappconfig`](provider/azappconfig)       | [Azure App Configuration](https://azure.microsoft.com/en-us/products/app-configuration)                                 |       ✓       | [azservicebus](notifier/azservicebus) |\n| [`azblob`](provider/azblob)                 | [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs)                                          |       ✓       | [azservicebus](notifier/azservicebus) |\n| [`secretmanager`](provider/secretmanager)   | [GCP Secret Manager](https://cloud.google.com/security/products/secret-manager)                                         |       ✓       | [pubsub](notifier/pubsub)             |\n| [`gcs`](provider/gcs)                       | [GCP Cloud Storage](https://cloud.google.com/storage)                                                                   |       ✓       | [pubsub](notifier/pubsub)             |\n\n[cobra](https://github.com/spf13/cobra) is supported through the [`pflag`](provider/pflag) loader, with the [\n`pflag.WithFlagSet`](https://pkg.go.dev/github.com/nil-go/konf/provider/pflag#WithFlagSet) option:\n\n```go\nconfig.Load(kflag.New(\u0026config, kflag.WithFlagSet(yourCobraCmd.Flags())))\n```\n\n## Custom Configuration Providers\n\nYou can Custom provider by implementing the `Loader` for static configuration loader (e.g [`fs`](provider/fs))\nor both `Loader` and `Watcher` for dynamic configuration loader (e.g. [`appconfig`](provider/appconfig)).\n","funding_links":[],"categories":["配置","Go","Configuration"],"sub_categories":["标准CLI","Standard CLI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnil-go%2Fkonf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnil-go%2Fkonf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnil-go%2Fkonf/lists"}