Configuration
Flora merges an ordered list of sources into one view, then decodes it. This page covers the source types, how precedence resolves conflicts, and the decoding rules.
Source types
| Constructor | Reads from | Typical use |
|---|---|---|
File(path) | A JSON, TOML, or INI file | Base configuration checked into the repo |
Dir(path) | Every file in a directory, sorted | Drop-in fragments under conf.d/ |
Env(prefix) | Environment variables with a prefix | Per-deployment overrides |
Flags(set) | A parsed flag.FlagSet | One-off command-line overrides |
Map(m) | An in-memory map[string]any | Defaults and tests |
Precedence
Sources passed to Load are applied in order. When two sources define the same key, the later source wins. A common, predictable ordering is:
flora.Load(&cfg,
flora.Map(defaults), // lowest priority
flora.File("config.toml"),
flora.Env("APP_"),
flora.Flags(fs), // highest priority
)
File formats
The format is chosen by file extension: .json, .toml, and .ini. To force a format regardless of extension, pass an explicit decoder:
flora.File("settings.conf", flora.As(flora.TOML))
Custom decoders
Any type implementing the Decoder interface can be registered for an extension:
type Decoder interface {
Decode(b []byte) (map[string]any, error)
}
flora.Register(".yaml", yamlDecoder{})
Decoding into structs
Field matching uses the flora tag, falling back to a case-insensitive match on the field name. Supported targets:
- All numeric, string, and boolean kinds
time.Duration(from strings like"30s") andtime.Time(RFC 3339)- Slices and maps of supported element types
- Nested structs and pointers to structs
- Any type implementing
encoding.TextUnmarshaler
WithStrict() to make Load return an error when a source contains a key with no matching field — useful for catching typos in production config.
Validation
Validation runs after decoding when WithValidation() is set. Rules are declared in the validate tag and combine with commas.
| Rule | Applies to | Meaning |
|---|---|---|
required | any | Must be set to a non-zero value |
min=N / max=N | numbers, strings, slices | Bounds on value, length, or count |
oneof=a b c | strings | Must equal one of the listed values |
hostport | strings | Must parse as host:port |
Validation errors are returned as a single ValidationError that lists every failing field, so one run reports all problems at once.
Reading keys directly
When a struct is overkill, load into a *Flora handle and use typed getters:
t, _ := flora.Open(flora.File("config.toml"))
addr := t.String("addr")
size := t.IntOr("cache.size_mb", 64)