Flora v1.6.2

Quick Start

This page loads a configuration file, layers environment overrides on top, and decodes the result into a struct.

1. Write a config file

Create config.toml next to your program:

# config.toml
addr     = "127.0.0.1:8080"
timeout  = 15
log_level = "info"

[cache]
enabled = true
size_mb = 64

2. Describe it as a struct

Fields are matched to keys with the flora struct tag. Nested tables map to nested structs.

type Config struct {
    Addr     string `flora:"addr"`
    Timeout  int    `flora:"timeout"`
    LogLevel string `flora:"log_level"`
    Cache    struct {
        Enabled bool `flora:"enabled"`
        SizeMB  int  `flora:"size_mb"`
    } `flora:"cache"`
}

3. Load it

Load takes a pointer to your struct and an ordered list of sources. Later sources override earlier ones.

func main() {
    var cfg Config
    err := flora.Load(&cfg,
        flora.File("config.toml"),
        flora.Env("APP_"),
    )
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("listening on %s", cfg.Addr)
}

4. Override from the environment

With the APP_ prefix registered, any matching variable wins over the file. Nested keys use __ as the separator:

APP_ADDR="0.0.0.0:9090" \
APP_CACHE__SIZE_MB=128 \
  ./myserver
How precedence works Sources are applied left to right, so Env overrides File here. See Configuration → Precedence for the full rules.

5. Validate before you trust it

Add lightweight checks with the validate tag, then call Load with WithValidation():

type Config struct {
    Addr    string `flora:"addr" validate:"required,hostport"`
    Timeout int    `flora:"timeout" validate:"min=1,max=300"`
}
err := flora.Load(&cfg,
    flora.File("config.toml"),
    flora.WithValidation(),
)

That is the whole loop: write a file, declare a struct, load, override, validate. Next, read the Configuration guide for source types and decoding details.