std.config

Layered configuration: environment wins over file, file wins over default.

import std.config

cfg = config.load({
    file: "config.toml",
    defaults: { port: 8080, host: "127.0.0.1" },
    env_prefix: "APP_",
    secrets: ["db_password"],
})

print(cfg.port)                 # APP_PORT, else the file, else 8080
sql.connect("...{reveal(cfg.db_password)}...")

Needs env and fs:read for package code.

The precedence, and why this way round

Environment beats file because a deployment must be able to override what a checked-in file says without editing it. That is the standard shape for a service.

This is the opposite of [std.defaults](./defaults.md), where the environment block in ecko.json overrides the shell. The two answer different questions:

precedencefor
std.configenv > file > defaulta deployed service reading its settings
std.defaultsfile > enva project pinning the environment its code needs

Use config for runtime settings that vary by environment; use defaults for project facts that should be the same everywhere.

Secret fields

Names listed in secrets arrive already wrapped in secret, so they render as [secret] through printing, logging and tracing, and need reveal to use. Declaring them is one line and it removes a whole class of accidental credential leak.

Environment names

env_prefix plus the uppercased key: port reads APP_PORT with the prefix above. A prefix is worth setting - it stops a generic name like PORT from being picked up from an unrelated part of the environment.

Types come from the defaults

A value from the environment is text. The defaults map tells config what type to coerce to, so port is an int because 8080 is. A default is therefore worth providing for every key, even where you expect it always to be set.

Errors

A missing file is an error unless a default covers everything; a malformed one raises { kind: "parse" } with the format and path. Validate at startup and fail loudly - a service that starts with half its configuration is worse than one that refuses to start.