All notable changes to oneenv are documented here.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.1.0] - 2026-07-19

Added

  • Example[T] — generates a ready-to-fill .env.example from a struct: each key with its default, preceded by comments carrying the desc tag, the Go type, and whether it is required. Defaults of secret fields are never written.
  • CLI -example flagoneenv -example writes a .env.example from the merged .env files: keys kept, values stripped, original comments above each key preserved, plus inferred-type and required comments. -o sets the output path (- for stdout, default .env.example).

1.0.0 - 2026-07-18

Initial release: a zero-dependency .env parser and struct decoder in one package.

Added

  • Core APIParse, Load, Unmarshal, LoadContext, ParseContext, and godotenv-style Read, LoadEnv, Overload.
  • Types — ints/uints/floats, bool, time.Duration, time.Time (with layout), slices, maps, pointers, nested structs, and any encoding.TextUnmarshaler.
  • Options — functional options: WithFiles, WithEnvFiles, WithEnvVar, WithPrefix, WithOverride, WithExpand, WithRequired, WithTagKey, WithLookuper, WithTypeParser, WithMutator, WithValidator, WithContext.
  • Tagsenv (with required, notEmpty, file, init, unset, secret options), default, separator/envSeparator, layout, envPrefix, desc, plus an env-* alias for every configuration tag (env-default, env-separator, env-description, env-layout, env-prefix, env-required, env-notempty, env-file, env-init, env-unset, env-secret). When both spellings are present the env-* form takes priority.
  • Environment-aware file cascadeWithEnvFiles() layers .env, .env.local, .env.<env> and .env.<env>.local by the active environment (APP_ENV, then GO_ENV; configurable with WithEnvVar). FilesFor exposes the resolved list.
  • Secretsenv:"X,file" reads a value from the file at the resolved path; env:"X,secret" with Redacted/RedactedMap masks values in output, and the Secret[T] wrapper keeps sensitive values out of logs and JSON while exposing the real value via Value().
  • Slices of structs — a []Struct field is decoded from indexed keys (SERVER_0_HOST, SERVER_1_HOST, …).
  • Hot reload — the oneenv/watch subpackage re-decodes on file change via native OS notifications (inotify on Linux, kqueue on BSD/macOS, ReadDirectoryChangesW on Windows) with modification-time polling as a fallback — all standard library, zero dependencies.
  • Marshal & UsageMarshal/MarshalMap render a struct back to .env; Usage prints a --help table of the variables a struct consumes.
  • Errors — positioned *ParseError (file:line) and every field failure collected at once via errors.Join; sentinels ErrNotAStruct, ErrRequired, ErrEmpty, ErrSecretFile, ErrUnsupportedType.
  • Hermetic testing — a Lookuper interface (MapLookuper, OSLookuper, PrefixLookuper) with no global state, parallel-safe by design.
  • Runnable examples for the full API surface, so pkg.go.dev renders interactive examples.