# Golang Spf13 Viper

> Maintain layered configuration when `github.com/spf13/viper` is already used or explicitly selected. Covers source precedence, environment and pflag binding, typed unmarshalling, isolated instances, and validated reloads; use a general configuration or CLI skill when Viper is absent.

- Skill: `reagin/golang-spf13-viper` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add reagin/golang-spf13-viper`
- Raw SKILL.md: https://api.skillmd.com/api/skills/reagin/golang-spf13-viper/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: reagin (https://skillmd.com/u/reagin)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/reagin/golang-spf13-viper

---


# Viper configuration

Preserve the application's documented keys, source precedence, defaults, decoding, validation, and reload behavior.

## Inspect before editing

Check `go.mod`, whether code uses a dedicated `*viper.Viper` or the global instance, enabled sources, key aliases, environment normalization, flag bindings, decode hooks, validation, reload, remote providers, and tests. Verify API and precedence details against the selected version and local wrappers.

## Source and key contract

Viper's documented precedence is explicit `Set`, flags, environment, config files, remote key/value stores, then defaults. Preserve the sources the application actually enables and test conflicts at the boundaries that matter.

- Treat key spelling, prefixing, case handling, and separators as compatibility-sensitive.
- Configure environment prefixes or replacers only when the application's key-to-environment mapping needs them; they are not universally required.
- Bind flags before the first lookup or decode that depends on their values. This can be during construction or a hook, depending on the program's actual order.
- A missing config file is ignorable only when the product contract says the file is optional. Distinguish not-found from parse, permission, and validation errors.
- Do not assume `AutomaticEnv` makes every environment-only key appear during struct unmarshalling. Register or bind the expected key set as needed by the selected version and cover env-only decoding in tests.

Read [references/api-and-testing.md](references/api-and-testing.md) when changing bindings, decoding, config-file discovery, or reload behavior. It maps concrete Viper calls to the contract they establish.

## Change a key coherently

Trace a key through its default, file spelling, environment mapping, flag binding, typed field, validation, consumers, documentation, and tests. A rename may require an explicit migration or alias when existing deployments persist the old key. Keep secret redaction and zero-versus-unset behavior consistent at every source.

When debugging precedence, inspect the value and whether its bound flag was changed instead of inferring the winning source from the final value alone.

## Decode once, then validate

Prefer decoding into a typed application-owned configuration and validating it before constructing dependent services. Use tags when file keys and Go field names do not map unambiguously; tags are not mandatory for fields whose mapping is already explicit and tested.

Preserve the distinction between unset, zero, and empty values. Weak decoding can be useful for string-based sources, but enable only conversions the application intends and test invalid inputs rather than accepting silent coercion.

Avoid scattering `Get*` calls through domain code. Inject the validated typed configuration or a narrow configuration interface where that matches the local architecture.

## Isolation and reload

Prefer a dedicated Viper instance when tests, subcommands, tenants, or embedded applications need independent state. If the project uses the global instance, isolate and restore it deliberately.

Viper does not promise safe concurrent reads and writes. For live reload, decode and validate a complete new snapshot, then publish it atomically or behind application-owned synchronization. Keep the previous valid snapshot when a reload fails. Ensure file-watching and remote-provider goroutines have an owner and shutdown path.

## Verification

Use fresh instances in focused tests where possible. Cover source precedence, environment-only keys, dotted/nested keys, aliases, flag changes, missing and malformed files, zero/empty values, decode hooks, validation failures, and concurrent reload behavior touched by the change.

Run formatting and relevant tests. Do not log full effective configuration when it can contain secrets.

## Official references

- [Viper package documentation](https://pkg.go.dev/github.com/spf13/viper)
- [Viper repository and README](https://github.com/spf13/viper)

