{"id":13430901,"url":"https://github.com/sethvargo/go-envconfig","last_synced_at":"2025-05-13T17:05:55.297Z","repository":{"id":38193648,"uuid":"269495508","full_name":"sethvargo/go-envconfig","owner":"sethvargo","description":"A Go library for parsing struct tags from environment variables.","archived":false,"fork":false,"pushed_at":"2025-04-11T18:15:01.000Z","size":180,"stargazers_count":1127,"open_issues_count":0,"forks_count":59,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-23T23:06:24.067Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sethvargo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","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":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-05T00:40:59.000Z","updated_at":"2025-04-22T11:29:15.000Z","dependencies_parsed_at":"2024-04-08T20:10:21.404Z","dependency_job_id":"c70957e6-8c2c-45ec-bddb-e38c14aff0cc","html_url":"https://github.com/sethvargo/go-envconfig","commit_stats":{"total_commits":86,"total_committers":17,"mean_commits":"5.0588235294117645","dds":0.2093023255813954,"last_synced_commit":"e51a54f91f5b9b2849b0cd0fb412e14afc9a4659"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fgo-envconfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fgo-envconfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fgo-envconfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fgo-envconfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sethvargo","download_url":"https://codeload.github.com/sethvargo/go-envconfig/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250528732,"owners_count":21445516,"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":[],"created_at":"2024-07-31T02:00:58.841Z","updated_at":"2025-05-13T17:05:55.284Z","avatar_url":"https://github.com/sethvargo.png","language":"Go","funding_links":[],"categories":["Go","Go (531)"],"sub_categories":[],"readme":"# Envconfig\n\n[![GoDoc](https://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godoc]\n\nEnvconfig populates struct field values based on environment variables or\narbitrary lookup functions. It supports pre-setting mutations, which is useful\nfor things like converting values to uppercase, trimming whitespace, or looking\nup secrets.\n\n## Usage\n\nDefine a struct with fields using the `env` tag:\n\n```go\ntype MyConfig struct {\n  Port     string `env:\"PORT\"`\n  Username string `env:\"USERNAME\"`\n}\n```\n\nSet some environment variables:\n\n```sh\nexport PORT=5555\nexport USERNAME=yoyo\n```\n\nProcess it using envconfig:\n\n```go\npackage main\n\nimport (\n  \"context\"\n  \"log\"\n\n  \"github.com/sethvargo/go-envconfig\"\n)\n\nfunc main() {\n  ctx := context.Background()\n\n  var c MyConfig\n  if err := envconfig.Process(ctx, \u0026c); err != nil {\n    log.Fatal(err)\n  }\n\n  // c.Port = 5555\n  // c.Username = \"yoyo\"\n}\n```\n\nYou can also use nested structs, just remember that any fields you want to\nprocess must be public:\n\n```go\ntype MyConfig struct {\n  Database *DatabaseConfig\n}\n\ntype DatabaseConfig struct {\n  Port     string `env:\"PORT\"`\n  Username string `env:\"USERNAME\"`\n}\n```\n\n## Configuration\n\nUse the `env` struct tag to define configuration. See the [godoc][] for usage\nexamples.\n\n-   `required` - marks a field as required. If a field is required, decoding\n    will error if the environment variable is unset.\n\n    ```go\n    type MyStruct struct {\n      Port string `env:\"PORT, required\"`\n    }\n    ```\n\n-   `default` - sets the default value for the environment variable is not set.\n    The environment variable must not be set (e.g. `unset PORT`). If the\n    environment variable is the empty string, envconfig considers that a \"value\"\n    and the default will **not** be used.\n\n    You can also set the default value to the value from another field or a\n    value from a different environment variable.\n\n    ```go\n    type MyStruct struct {\n      Port string `env:\"PORT, default=5555\"`\n      User string `env:\"USER, default=$CURRENT_USER\"`\n    }\n    ```\n\n    As a special case where the default value should contain a literal `$`,\n    escape it with a backslash. Unfortunately this requires a double backslash\n    in the struct tag:\n\n    ```go\n    type MyStruct struct {\n      Amount string `env:\"AMOUNT, default=\\\\$5.00\"` // Default: $5.00\n    }\n    ```\n\n    To have a literal backslash followed by a `$`, escape the backslash:\n\n    ```go\n    type MyStruct struct {\n      Filepath string `env:\"FILEPATH, default=C:\\\\Personal\\\\\\\\$name\"` // Default: C:\\Personal\\$name\n    }\n    ```\n\n-   `prefix` - sets the prefix to use for looking up environment variable keys\n    on child structs and fields. This is useful for shared configurations:\n\n    ```go\n    type RedisConfig struct {\n      Host string `env:\"REDIS_HOST\"`\n      User string `env:\"REDIS_USER\"`\n    }\n\n    type ServerConfig struct {\n      // CacheConfig will process values from $CACHE_REDIS_HOST and\n      // $CACHE_REDIS_USER respectively.\n      CacheConfig *RedisConfig `env:\", prefix=CACHE_\"`\n\n      // RateLimitConfig will process values from $RATE_LIMIT_REDIS_HOST and\n      // $RATE_LIMIT_REDIS_USER respectively.\n      RateLimitConfig *RedisConfig `env:\", prefix=RATE_LIMIT_\"`\n    }\n    ```\n\n-   `overwrite` - force overwriting existing non-zero struct values if the\n    environment variable was provided.\n\n    ```go\n    type MyStruct struct {\n      Port string `env:\"PORT, overwrite\"`\n    }\n    ```\n\n    The rules for overwrite + default are:\n\n    -   If the struct field has the zero value and a default is set:\n\n        -   If no environment variable is specified, the struct field will be\n            populated with the default value.\n\n        -   If an environment variable is specified, the struct field will be\n            populate with the environment variable value.\n\n    -   If the struct field has a non-zero value and a default is set:\n\n        -   If no environment variable is specified, the struct field's existing\n            value will be used (the default is ignored).\n\n        -   If an environment variable is specified, the struct field's existing\n            value will be overwritten with the environment variable value.\n\n-   `delimiter` - choose a custom character to denote individual slice and map\n    entries. The default value is the comma (`,`).\n\n    ```go\n    type MyStruct struct {\n      MyVar []string `env:\"MYVAR, delimiter=;\"`\n    ```\n\n    ```bash\n    export MYVAR=\"a;b;c;d\" # []string{\"a\", \"b\", \"c\", \"d\"}\n    ```\n\n-   `separator` - choose a custom character to denote the separation between\n    keys and values in map entries. The default value is the colon (`:`) Define\n    a separator with `separator`:\n\n    ```go\n    type MyStruct struct {\n      MyVar map[string]string `env:\"MYVAR, separator=|\"`\n    }\n    ```\n\n    ```bash\n    export MYVAR=\"a|b,c|d\" # map[string]string{\"a\":\"b\", \"c\":\"d\"}\n    ```\n\n-   `noinit` - do not initialize struct fields unless environment variables were\n    provided. The default behavior is to deeply initialize all fields to their\n    default (zero) value.\n\n    ```go\n    type MyStruct struct {\n      MyVar *url.URL `env:\"MYVAR, noinit\"`\n    }\n    ```\n\n-   `decodeunset` - force envconfig to run decoders even on unset environment\n    variable values. The default behavior is to skip running decoders on unset\n    environment variable values.\n\n    ```go\n    type MyStruct struct {\n      MyVar *url.URL `env:\"MYVAR, decodeunset\"`\n    }\n    ```\n\n\n## Decoding\n\n\u003e [!NOTE]\n\u003e\n\u003e Complex types are only decoded or unmarshalled when the environment variable\n\u003e is defined or a default value is specified.\n\n\n### Durations\n\nIn the environment, `time.Duration` values are specified as a parsable Go\nduration:\n\n```go\ntype MyStruct struct {\n  MyVar time.Duration `env:\"MYVAR\"`\n}\n```\n\n```bash\nexport MYVAR=\"10m\" # 10 * time.Minute\n```\n\n\n### TextUnmarshaler / BinaryUnmarshaler\n\nTypes that implement `TextUnmarshaler` or `BinaryUnmarshaler` are processed as\nsuch.\n\n\n### json.Unmarshaler\n\nTypes that implement `json.Unmarshaler` are processed as such.\n\n\n### gob.Decoder\n\nTypes that implement `gob.Decoder` are processed as such.\n\n\n### Slices\n\nSlices are specified as comma-separated values.\n\n```go\ntype MyStruct struct {\n  MyVar []string `env:\"MYVAR\"`\n}\n```\n\n```bash\nexport MYVAR=\"a,b,c,d\" # []string{\"a\", \"b\", \"c\", \"d\"}\n```\n\nNote that byte slices are special cased and interpreted as strings from the\nenvironment.\n\n\n### Maps\n\nMaps are specified as comma-separated key:value pairs:\n\n```go\ntype MyStruct struct {\n  MyVar map[string]string `env:\"MYVAR\"`\n}\n```\n\n```bash\nexport MYVAR=\"a:b,c:d\" # map[string]string{\"a\":\"b\", \"c\":\"d\"}\n```\n\n\n### Structs\n\nEnvconfig walks the entire struct, including nested structs, so deeply-nested\nfields are also supported.\n\nIf a nested struct is a pointer type, it will automatically be instantianted to\nthe non-nil value. To change this behavior, see\n[Initialization](#Initialization).\n\n\n### Custom Decoders\n\nYou can also define your own decoders.\n\n```go\ntype MyCustomType struct {\n  value string\n}\n\nfunc (t *MyCustomType) EnvDecode(ctx context.Context, val string) error {\n  resolved := someComplexFunction(val)\n  t.value = resolved\n  return nil\n}\n```\n\nSee the [godoc][godoc] for more information.\n\n\n## Testing\n\nRelying on the environment in tests can be troublesome because environment\nvariables are global, which makes it difficult to parallelize the tests.\nEnvconfig supports extracting data from anything that returns a value:\n\n```go\nlookuper := envconfig.MapLookuper(map[string]string{\n  \"FOO\": \"bar\",\n  \"ZIP\": \"zap\",\n})\n\nvar config Config\nenvconfig.ProcessWith(ctx, \u0026envconfig.Config{\n  Target:   \u0026config,\n  Lookuper: lookuper,\n})\n```\n\nNow you can parallelize all your tests by providing a map for the lookup\nfunction. In fact, that's how the tests in this repo work, so check there for an\nexample.\n\nYou can also combine multiple lookupers with `MultiLookuper`. See the GoDoc for\nmore information and examples.\n\n\n[godoc]: https://pkg.go.dev/mod/github.com/sethvargo/go-envconfig\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethvargo%2Fgo-envconfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsethvargo%2Fgo-envconfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethvargo%2Fgo-envconfig/lists"}