Read dotenv¶
The core reads and writes only YAML. dotenv (.env) comes from a sibling module,
config-dotenv, which adds nothing to
your dependency graph — a .env file is read with the standard library.
import (
"gitlab.com/phpboyscout/go/config"
configdotenv "gitlab.com/phpboyscout/go/config-dotenv"
)
store, err := config.NewStore(ctx,
config.WithFiles(fsys, "/etc/app.yaml"), // YAML, the default
config.WithBackend(configdotenv.New(fsys, "/etc/app.env")), // outranks it
)
When you do not need this¶
If the values are already exported into the process environment — a container
runtime, a systemd unit, a CI job — then WithEnv reads them with
no module and no file.
Reach for config-dotenv when a .env file exists but nothing has applied it: local
development, or a compose file whose env_file your process never sees. It is
read-only, so it is a source of values and never a write target.
Keys nest on underscores¶
A dotenv key is lower-cased and its underscores become dotted-key separators:
host := store.View().GetString("database.host") // "localhost"
port := store.View().GetInt("database.port") // 5432
A dotenv layer therefore merges into a nested YAML or JSON one by the same paths. The rule is
deterministic — the same mapping the environment backend uses for an unmatched variable — so a
key with a literal underscore in its name cannot be expressed, by design. An export prefix is
accepted, and surrounding single or double quotes are stripped.
No interpolation¶
A ${VAR} in a value is left as written, never expanded:
Expanding it would read the process environment through a side door the Store does not own —
exactly the unprefixed-environment leak the environment backend's required prefix exists to
prevent. If you want environment values, add config.WithEnv("PREFIX") as an ordinary layer,
where the prefix applies and provenance names the variable.
Read-only¶
Values are strings; the read path casts. The format is read-only.
What it costs¶
| Modules added | none — everything it links comes from the config graph, and an allowlist test in the module fails if that changes |
A .env file is parsed with the standard library, so there is no parser module — and no
filesystem library either, because you supply the config.FS.
Related¶
- Support a new file format — how an adapter like this is built and tested
- Bind CLI flags and environment — the other ways flat, external inputs become layers