Options Reference
7 minute read
Reference for all option functions passed to New and MustNew.
Option Type
Option is a functional option that applies to an internal builder during construction, then produces the public *Config. It is not func(*Config). Pass only non-nil values from WithFile, WithEnv, and other With… helpers. Validation errors from options are collected when you call New (or when MustNew panics).
Environment Variable Expansion
All path-based options (WithFile, WithFileAs, WithConsul, WithConsulAs, WithFileDumper, WithFileDumperAs) support environment variable expansion in paths. This makes it easy to use different paths based on your environment.
Supported syntax:
${VAR}- Braced variable name$VAR- Simple variable name
Note: Shell-style defaults like ${VAR:-default} are NOT supported. Set defaults in your code before calling the option.
Examples:
// Environment-based Consul path
config.WithConsul("${APP_ENV}/service.yaml")
// When APP_ENV=production, expands to: "production/service.yaml"
// Config directory from environment
config.WithFile("${CONFIG_DIR}/app.yaml")
// When CONFIG_DIR=/etc/myapp, expands to: "/etc/myapp/app.yaml"
// Multiple variables
config.WithFile("${REGION}/${ENV}/settings.yaml")
// When REGION=us-west and ENV=staging, expands to: "us-west/staging/settings.yaml"
// Output directory
config.WithFileDumper("${LOG_DIR}/effective-config.yaml")
// When LOG_DIR=/var/log, expands to: "/var/log/effective-config.yaml"
Handling unset variables:
If an environment variable is not set, it expands to an empty string:
// If APP_ENV is not set:
config.WithConsul("${APP_ENV}/service.yaml") // Expands to: "/service.yaml"
To provide defaults, set them in your code:
if os.Getenv("APP_ENV") == "" {
os.Setenv("APP_ENV", "development")
}
config.WithConsul("${APP_ENV}/service.yaml") // Uses "development" if not set
Source Options
Source options specify where configuration data comes from.
WithFile
func WithFile(path string) Option
Loads configuration from a file with automatic format detection based on extension.
Parameters:
path- Path to configuration file.
Supported extensions:
.json- JSON format..yaml,.yml- YAML format..toml- TOML format.
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithFile("config.json"),
)
Error conditions:
- File does not exist (error occurs during
Load(), not initialization) - Extension not recognized
WithFileAs
func WithFileAs(path string, codecType codec.Type) Option
Loads configuration from a file with explicit format specification.
Parameters:
path- Path to configuration file.codecType- Codec type likecodec.TypeYAMLorcodec.TypeJSON.
Example:
cfg := config.MustNew(
config.WithFileAs("config.txt", codec.TypeYAML),
config.WithFileAs("settings.conf", codec.TypeJSON),
)
Use when: File extension doesn’t match its format.
WithEnv
func WithEnv(prefix string) Option
Loads configuration from environment variables with the given prefix.
Parameters:
prefix- Prefix to filter environment variables (e.g., “APP_”, “MYAPP_”)
Naming convention:
PREFIX_KEY→keyPREFIX_SECTION_KEY→section.keyPREFIX_A_B_C→a.b.c
Example:
cfg := config.MustNew(
config.WithEnv("MYAPP_"),
)
// Environment: MYAPP_SERVER_PORT=8080
// Maps to: server.port = 8080
See also: Environment Variables Guide
WithConsul
func WithConsul(path string) Option
Loads configuration from HashiCorp Consul. The format is detected from the file extension.
CONSUL_HTTP_ADDR is required. If it is not set, New/MustNew returns a validation error at construction. For optional Consul (e.g. development without Consul), use WithConsulOptional instead.
Parameters:
path- Consul key path (format detected from extension)
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithConsul("production/service.json"), // Fails at construction if CONSUL_HTTP_ADDR is unset
)
Environment variables:
CONSUL_HTTP_ADDR- Consul server address (required)CONSUL_HTTP_TOKEN- Access token for authentication (optional)
WithConsulAs
func WithConsulAs(path string, codecType codec.Type) Option
Loads configuration from Consul with explicit format. Use this when the key path doesn’t have an extension.
CONSUL_HTTP_ADDR is required. If it is not set, New/MustNew returns a validation error at construction. For optional Consul, use WithConsulAsOptional instead.
Parameters:
path- Consul key pathcodecType- Codec type (likecodec.TypeYAMLorcodec.TypeJSON)
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithConsulAs("config/app", codec.TypeYAML), // No extension in key
)
Environment variables:
CONSUL_HTTP_ADDR- Consul server address (required)CONSUL_HTTP_TOKEN- Access token for authentication (optional)
WithConsulOptional
func WithConsulOptional(path string) Option
Adds a Consul source only when CONSUL_HTTP_ADDR is set. If it is not set, this option is a no-op (no source added, no error). Use for development without Consul; use WithConsul when Consul is required and should fail at construction if the env is missing.
Parameters:
path- Consul key path (format detected from extension)
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithConsulOptional("production/service.yaml"), // No-op when CONSUL_HTTP_ADDR is unset
)
WithConsulAsOptional
func WithConsulAsOptional(path string, codecType codec.Type) Option
Adds a Consul source with explicit format only when CONSUL_HTTP_ADDR is set. If it is not set, this option is a no-op. Use for development without Consul; use WithConsulAs when Consul is required.
Parameters:
path- Consul key pathcodecType- Codec type (e.g.codec.TypeYAML,codec.TypeJSON)
Example:
cfg := config.MustNew(
config.WithConsulAsOptional("production/service", codec.TypeJSON),
)
WithContent
func WithContent(data []byte, codecType codec.Type) Option
Loads configuration from a byte slice.
Parameters:
data- Configuration data as bytescodecType- Codec type for decoding
Example:
configData := []byte(`{"server": {"port": 8080}}`)
cfg := config.MustNew(
config.WithContent(configData, codec.TypeJSON),
)
Use cases:
- Testing
- Dynamic configuration
- Embedded configuration
WithSource
func WithSource(loader Source) Option
Adds a custom configuration source.
Parameters:
loader- Custom source implementing theSourceinterface
Source interface:
type Source interface {
Load(ctx context.Context) (map[string]any, error)
}
Example:
type CustomSource struct{}
func (s *CustomSource) Load(ctx context.Context) (map[string]any, error) {
return map[string]any{"key": "value"}, nil
}
cfg := config.MustNew(
config.WithSource(&CustomSource{}),
)
Validation Options
Validation options enable configuration validation.
WithBinding
func WithBinding(v any) Option
Binds configuration to a Go struct and optionally validates it.
Parameters:
v- Pointer to struct to bind configuration to
Example:
type AppSettings struct {
Port int `config:"port"`
}
var settings AppSettings
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithBinding(&settings),
)
Validation: If the struct implements Validate() error, it will be called after binding.
Requirements:
- Must pass a pointer to the struct
- Struct fields must have
config:"name"tags
See also: Struct Binding Guide
WithTag
func WithTag(tagName string) Option
Changes the struct tag name used for binding (default: “config”).
Parameters:
tagName- Tag name to use instead of “config”
Example:
type AppSettings struct {
Port int `yaml:"port"`
}
var settings AppSettings
cfg := config.MustNew(
config.WithTag("yaml"),
config.WithBinding(&settings),
)
Use when: You want to reuse existing struct tags (e.g., json, yaml).
WithValidator
func WithValidator(fn func(map[string]any) error) Option
Registers a custom validation function for the configuration map.
Parameters:
fn- Validation function that receives the merged configuration
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithValidator(func(data map[string]any) error {
port, ok := data["port"].(int)
if !ok || port <= 0 {
return errors.New("port must be a positive integer")
}
return nil
}),
)
Timing: Runs after sources are merged and after JSON Schema validation (if any), before struct binding.
Multiple validators: You can register multiple validators; all will be executed.
WithJSONSchema
func WithJSONSchema(schema []byte) Option
Validates configuration against a JSON Schema.
Parameters:
schema- JSON Schema as bytes
Example:
schemaBytes, _ := os.ReadFile("schema.json")
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithJSONSchema(schemaBytes),
)
Schema validation:
- Runs after sources are merged
- Runs before custom validators and struct binding
- Uses github.com/santhosh-tekuri/jsonschema/v6
See also: Validation Guide
Dumper Options
Dumper options specify where to write configuration.
WithFileDumper
func WithFileDumper(path string) Option
Writes configuration to a file with automatic format detection.
Parameters:
path- Output file path (format detected from extension)
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithEnv("APP_"),
config.WithFileDumper("effective-config.yaml"),
)
cfg.Load(context.Background())
cfg.Dump(context.Background()) // Writes to effective-config.yaml
Default permissions: 0644 (owner read/write, group/others read)
WithFileDumperAs
func WithFileDumperAs(path string, codecType codec.Type) Option
Writes configuration to a file with explicit format specification.
Parameters:
path- Output file pathcodecType- Codec type for encoding
Example:
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithFileDumperAs("output.json", codec.TypeJSON),
)
WithDumper
func WithDumper(dumper Dumper) Option
Adds a custom configuration dumper.
Parameters:
dumper- Custom dumper implementing theDumperinterface
Dumper interface:
type Dumper interface {
Dump(ctx context.Context, values *map[string]any) error
}
Example:
type CustomDumper struct{}
func (d *CustomDumper) Dump(ctx context.Context, values *map[string]any) error {
// Write *values somewhere; do not mutate the map unless you own the contract
return nil
}
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithDumper(&CustomDumper{}),
)
Option Composition
Options are applied in the order they are passed to New() or MustNew():
cfg := config.MustNew(
// 1. Load base config
config.WithFile("config.yaml"),
// 2. Load environment-specific config
config.WithFile("config.prod.yaml"),
// 3. Override with environment variables (highest priority)
config.WithEnv("APP_"),
// 4. Set up validation
config.WithJSONSchema(schemaBytes),
config.WithValidator(customValidation),
// 5. Bind to struct
config.WithBinding(&appConfig),
// 6. Set up dumper
config.WithFileDumper("effective-config.yaml"),
)
Source Precedence
When multiple sources are configured, later sources override earlier ones:
cfg := config.MustNew(
config.WithFile("config.yaml"), // Priority 1 (lowest)
config.WithFile("config.prod.yaml"), // Priority 2
config.WithEnv("APP_"), // Priority 3 (highest)
)
Validation Order
Validation happens in this sequence during Load():
- Load and merge all sources
- JSON Schema validation (if configured)
- Custom validation functions (if configured)
- Struct binding (if configured)
- Struct
Validate()method (if implemented)
Common Patterns
Pattern 1: Basic Configuration
cfg := config.MustNew(
config.WithFile("config.yaml"),
)
Pattern 2: Environment Override
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithEnv("APP_"),
)
Pattern 3: Multi-Environment
env := os.Getenv("APP_ENV")
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithFile("config."+env+".yaml"),
config.WithEnv("APP_"),
)
Pattern 4: With Validation
var appConfig AppConfig
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithEnv("APP_"),
config.WithBinding(&appConfig),
)
Pattern 5: Production Setup
var appConfig AppConfig
schemaBytes, _ := os.ReadFile("schema.json")
cfg := config.MustNew(
config.WithFile("config.yaml"),
config.WithEnv("APP_"),
config.WithJSONSchema(schemaBytes),
config.WithBinding(&appConfig),
config.WithFileDumper("effective-config.yaml"),
)
Next Steps
- See API Reference for Config methods
- Review Codecs for format support
- Check Examples for usage patterns
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.