|
| 1 | +# envstruct |
| 2 | + |
| 3 | +**Replacement for:** [kelseyhightower/envconfig](https://github.com/kelseyhightower/envconfig) |
| 4 | +**Language:** Go |
| 5 | +**Package:** `github.com/agentine/envstruct` |
| 6 | + |
| 7 | +## Why |
| 8 | + |
| 9 | +kelseyhightower/envconfig has 8,524 importers and 20.2K GitHub dependents but has been dormant since May 2019 (last release v1.4.0). The sole maintainer is no longer active in OSS. There are 27 open issues and 31 open PRs with zero maintainer engagement. Existing alternatives (caarlos0/env, sethvargo/go-envconfig) have not captured envconfig's market share. |
| 10 | + |
| 11 | +## Scope |
| 12 | + |
| 13 | +A Go library that populates struct fields from environment variables using struct tags. Drop-in replacement for envconfig with modern Go practices. |
| 14 | + |
| 15 | +## Core Features |
| 16 | + |
| 17 | +1. **Struct tag parsing** — `env:"VAR_NAME"` tags to map env vars to struct fields |
| 18 | +2. **Type support** — string, int (all sizes), uint, float, bool, time.Duration, url.URL, custom types |
| 19 | +3. **Prefix support** — scoped env var lookup via configurable prefix (e.g., `APP_`) |
| 20 | +4. **Nested structs** — flatten or use delimiter-separated names (e.g., `APP_DB_HOST`) |
| 21 | +5. **Required fields** — `env:"VAR_NAME,required"` tag option |
| 22 | +6. **Default values** — `env:"VAR_NAME" default:"value"` tag |
| 23 | +7. **Custom decoders** — `Decoder` interface for user-defined types |
| 24 | +8. **Slice/map support** — comma-separated values for slices, key=value pairs for maps |
| 25 | +9. **Usage generation** — auto-generate usage text from struct tags |
| 26 | +10. **Error reporting** — clear error messages with field name, expected type, and env var name |
| 27 | + |
| 28 | +## Architecture |
| 29 | + |
| 30 | +``` |
| 31 | +envstruct/ |
| 32 | +├── envstruct.go # Core Process/MustProcess functions |
| 33 | +├── decoder.go # Type decoders and Decoder interface |
| 34 | +├── tags.go # Struct tag parsing |
| 35 | +├── usage.go # Usage text generation |
| 36 | +├── errors.go # Typed error types |
| 37 | +├── envstruct_test.go # Core tests |
| 38 | +├── decoder_test.go # Decoder tests |
| 39 | +├── usage_test.go # Usage tests |
| 40 | +├── example_test.go # Runnable examples |
| 41 | +├── go.mod |
| 42 | +├── go.sum |
| 43 | +└── README.md |
| 44 | +``` |
| 45 | + |
| 46 | +## API Surface |
| 47 | + |
| 48 | +```go |
| 49 | +// Process populates a struct from environment variables. |
| 50 | +func Process(prefix string, spec interface{}) error |
| 51 | + |
| 52 | +// MustProcess is like Process but panics on error. |
| 53 | +func MustProcess(prefix string, spec interface{}) |
| 54 | + |
| 55 | +// Usage writes a usage message to the given writer. |
| 56 | +func Usage(prefix string, spec interface{}, out io.Writer) error |
| 57 | + |
| 58 | +// Decoder is implemented by types that can decode themselves from a string. |
| 59 | +type Decoder interface { |
| 60 | + Decode(value string) error |
| 61 | +} |
| 62 | + |
| 63 | +// Setter is implemented by types that can set themselves from a string (envconfig compat). |
| 64 | +type Setter interface { |
| 65 | + Set(value string) error |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +## Migration Path |
| 70 | + |
| 71 | +- Same `Process(prefix, &spec)` function signature as envconfig |
| 72 | +- Supports envconfig's struct tag format for easy migration |
| 73 | +- Also supports `env:"NAME"` tag format (more conventional) |
| 74 | +- Decoder interface is compatible with envconfig's interface |
| 75 | + |
| 76 | +## Deliverables |
| 77 | + |
| 78 | +1. Core library with full type support |
| 79 | +2. Comprehensive test suite (>90% coverage) |
| 80 | +3. README with migration guide from envconfig |
| 81 | +4. Runnable examples |
| 82 | +5. CI configuration (GitHub Actions) |
| 83 | + |
| 84 | +## Non-Goals |
| 85 | + |
| 86 | +- File-based config (.env, YAML, TOML) — use dedicated libraries |
| 87 | +- Config hot-reloading — environment variables are read once at startup |
| 88 | +- CLI flag parsing — separate concern |
0 commit comments