Configuration
Anvil keeps application configuration in application code. It provides small helpers for common boot-time configuration patterns, but it does not own your environment model.
Environment Fallbacks
Section titled “Environment Fallbacks”addr := anvil.Env("ADDR", ":3000")Env returns the fallback when the key is empty, the variable is missing, or
the variable is set to an empty string.
Anvil mode helpers parse deployment mode values:
mode := anvil.MustMode(anvil.Env("ANVIL_MODE", "development"))Modes are useful for enabling development-only diagnostics or strict production settings.
ModeFromEnv() checks ANVIL_ENV, APP_ENV, and GO_ENV, in that order.
ModeFromEnv("CUSTOM_ENV") checks only the keys you pass. Empty key names are
rejected.
Accepted values:
- Development: empty string,
dev,development,local. - Production:
prod,production. - Test:
test,testing.
Unknown values return an error from ParseMode and panic from MustMode.
Typed Config
Section titled “Typed Config”LoadConfig maps environment variables into a struct:
type Config struct { Addr string `env:"ADDR" default:":3000"` Database string `env:"DATABASE_URL" required:"true"`}
cfg := anvil.MustConfig[Config]()Call config loading from application startup code, usually in main before
app.Wire() or before app.Run(). The helper uses reflection where it is
called; Anvil does not run it automatically. Missing required values stop
startup before transports listen when the composition root returns or logs that
error before running the app.
LoadConfig[T] expects T to be a struct. It walks exported settable fields
and reads fields tagged with env:"NAME".
Field behavior:
default:"value"is used only when the environment variable is not set.- If the environment variable is set to an empty string, the default is not used.
required:"true"fails when the final value is empty.- Nested structs are loaded recursively, except for
time.Duration. - Unsupported field types return an error.
- Fields without an
envtag are ignored unless they are nested structs. - Unexported fields are ignored because reflection cannot set them.
[]stringvalues are split on commas and each item is trimmed.- Only
[]stringis supported for slices.
Supported field types:
stringbool, parsed withstrconv.ParseBool- Signed and unsigned integers, parsed as base-10 numbers
- Floats
time.Duration, parsed withtime.ParseDuration[]stringfrom comma-separated values, with each item trimmed- Nested structs, except
time.Duration
String slices preserve empty items between commas. For example,
FEATURES=search,,billing becomes []string{"search", "", "billing"}.
MustConfig panics by design. Use it in startup code only. Use LoadConfig
when the composition root returns the error explicitly.
Nested structs are loaded recursively before env tags are considered on that
field. Put env tags on the leaf fields that receive values.
Driver Config
Section titled “Driver Config”Driver options live in driver packages:
app := anvil.New( httpstd.Driver(httpstd.Options{ MaxBodyBytes: 8 << 20, }),)Driver options configure driver-owned behavior, such as body limits, codecs, WebSocket origin checks, native Fiber or gRPC options, and broker settings.
In an edge application, Anvil runs the public HTTP-family listener. Put
public listener timeouts on anvil.WithListener; driver Server fields only
apply when that driver runs standalone.
Listener Config
Section titled “Listener Config”When HTTP, GraphQL, or gRPC drivers are registered, Anvil runs the shared
HTTP-family listener. Use anvil.WithListener for net/http.Server settings
that belong to that edge listener:
app := anvil.New( anvil.WithListener(&http.Server{ ReadHeaderTimeout: 2 * time.Second, MaxHeaderBytes: 32 << 10, }), httpstd.Driver(),)The server Handler must be nil because Anvil installs the edge dispatcher.