| name | golang-spf13-viper |
| description | Golang configuration library using spf13/viper — layered precedence (flag > env > file > KV > default), AutomaticEnv, ReadInConfig, Unmarshal + mapstructure, WatchConfig hot reload. Apply when using/adopting viper or the codebase imports github.com/spf13/viper. CLI commands: golang-spf13-cobra. |
| user-invocable | true |
| license | MIT |
| compatibility | Designed for Claude Code, Codex or similar harness, and for projects using Golang. |
| metadata | {"author":"samber","version":"1.1.0","openclaw":{"emoji":"🔧","homepage":"https://github.com/samber/cc-skills-golang","requires":{"bins":"[Truncated]"},"install":[],"skill-library-version":"1.21.0"}} |
| allowed-tools | Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__* |
| paths | ["**/*.go"] |
Persona: You are a Go engineer who treats configuration as a layered system. Flag beats env beats file beats default — and you bind every key so all four layers stay reachable through one API.
Using spf13/viper for layered configuration in Go
Viper resolves configuration values from multiple sources in a fixed precedence order. It has no user-facing surface — it doesn't define commands or flags. Its job is to answer "what is the value of key X right now?" by walking its source layers from highest to lowest priority.
Official Resources:
This skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See samber/cc-skills-golang@golang-pkg-go-dev skill (godig) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See samber/cc-skills-golang@golang-gopls skill (gopls). Context7 remains a fallback for docs not indexed on pkg.go.dev.
go get github.com/spf13/viper@latest
Viper vs. cobra
Cobra owns the command tree — subcommands, flags, arg validation, completions. Viper owns configuration resolution — it answers "what is the value of key X?" by walking its source layers. Viper has no user-facing surface; it is purely a key-value resolver. Use cobra alone for flag-only CLIs; viper alone for config-file daemons; both when you need both, binding flags at PersistentPreRunE via BindPFlag.
→ See samber/cc-skills-golang@golang-spf13-cobra for the cobra side of this integration.
The precedence pipeline
Viper resolves a key by walking sources in this order (first set value wins):
1. explicit Set() — viper.Set("key", val) highest priority
2. flag — bound pflag.Flag
3. env var — BindEnv / AutomaticEnv
4. config file — ReadInConfig / MergeInConfig
5. KV remote — etcd / Consul
6. default — viper.SetDefault("key", val) lowest priority
This pipeline is fixed and cannot be reordered. Understanding it prevents most viper bugs: a key that "should" come from a config file may be shadowed by an env var or a flag with a default value.
Sources and config files
viper.SetConfigName()
viper.AddConfigPath()
err := viper.ReadInConfig(); err != {
notFound *viper.ConfigFileNotFoundError
!errors.As(err, ¬Found) {
fmt.Errorf(, err)
}
}