golang-spf13-viper

Configure layered Go application settings with spf13/viper across flags, env vars, files, and defaults.

Updated May 9, 2026
One-click install
npx skills add https://github.com/LuminaVault/LuminaVaultShared --skill golang-spf13-viper-luminavault
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: golang-spf13-viper
Source: https://github.com/LuminaVault/LuminaVaultShared/tree/main/.agents/skills/golang-spf13-viper
Command: npx skills add https://github.com/LuminaVault/LuminaVaultShared --skill golang-spf13-viper-luminavault

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires github.com/spf13/viper, and includes references (resource) components.

What problem does it solve? Go services often misbehave because configuration values come from multiple sources — flags, environment variables, config files, and defaults — and viper's precedence rules, env key mapping, and unmarshaling behavior are easy to get wrong. This Skill provides the correct patterns for wiring viper so nested keys resolve, optional config files don't crash services, and tests stay isolated. ## Core Features & Use Cases - Layered precedence and env binding: Wire SetEnvPrefix, SetEnvKeyReplacer, and AutomaticEnv together so nested keys like database.host resolve to MYAPP_DATABASE_HOST, and bind cobra flags via BindPFlag before Execute(). - Struct unmarshaling and hot reload: Use mapstructure tags, UnmarshalKey, DecodeHooks for time.Duration, and race-safe WatchConfig patterns with validate-then-swap reloads. - Test isolation: Create viper.New() instances per test instead of the global instance to eliminate order-dependent flaky tests. - Use Case: A Go HTTP service reads a YAML config file, overrides values with environment variables, and hot-reloads on change — this Skill shows the exact setup including graceful ConfigFileNotFoundError handling. ## Quick Start Ask the agent to set up viper configuration for your Go service with env var binding, an optional YAML config file, and struct unmarshaling.

Frequently Asked Questions about golang-spf13-viper

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I bind environment variables to nested viper keys in Go?▼

Call SetEnvPrefix, SetEnvKeyReplacer(strings.NewReplacer(".", "_")), and AutomaticEnv together before reading values. Without the key replacer, viper looks up MYAPP_DATABASE.HOST with the dot preserved, so nested keys like database.host never match.

How do I use viper with cobra flags in a Go CLI?▼

Define the flag on the cobra command, then call viper.BindPFlag in init() or PersistentPreRunE, never in RunE. Cobra parses flags before RunE executes, so binding there misses the flag's Changed state and viper returns defaults.

Can I use viper without cobra for a Go HTTP service?▼

Yes, viper works standalone for services with no command tree. Cobra only owns subcommands and flag parsing; a plain HTTP service can use viper alone for YAML config files and environment variables.

Why does viper.Unmarshal leave my struct fields at zero values?▼

Missing mapstructure struct tags are the usual cause — mapstructure matches case-insensitively but does not convert underscores to camelCase, so max_conn never maps to MaxConn. Add mapstructure:"max_conn" tags, and register a StringToTimeDurationHookFunc decode hook for time.Duration fields.

Why are my viper config tests flaky and order-dependent?▼

The top-level viper functions share one global instance, so state set in one test leaks into the next. Create a fresh viper.New() per test and inject it into your application code instead of using the global.

Why does viper WatchConfig not fire when I save in vim?▼

Vim and many editors write atomically via rename, which replaces the inode fsnotify is watching, so the OnConfigChange callback may not fire. Test hot reload with direct writes like os.WriteFile instead of editor saves.