Viper

A complete configuration solution for Go applications, merging flags, env vars, config files, and remote stores into one API.

Library
Go
vv1.21.0
30,485 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
47 /100 Fair
Development Activity 0
Maintenance 20
Community 68
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
76 /100 Good
Architecture 80
Code Quality 82
Innovation 55
Learning Curve 85

Viper is a configuration management library for Go that unifies every common configuration source — command-line flags, environment variables, JSON/TOML/YAML/INI/envfile/Java-properties files, remote key/value stores like etcd and Consul, and explicit in-code overrides — behind a single, consistent get/set API. Rather than forcing an application to wire up separate parsers for each source, Viper applies a fixed precedence order (explicit Set calls, flags, env vars, config file, remote store, defaults) so callers can just ask for a value by key and get the right one regardless of where it came from.

It is designed as the natural companion to Cobra (both maintained by the same author), binding directly to pflag-based command flags, but it works equally well standalone. Beyond static lookups, Viper supports live config-file watching via fsnotify with change callbacks, key aliasing for painless refactors, and unmarshaling straight into structs or maps via mapstructure. It has been adopted by large Go projects including Hugo, Docker Notary, and DigitalOcean’s doctl, and remains one of the most widely used configuration libraries in the Go ecosystem.

What You Get

  • A unified Get/GetString/GetInt/GetBool-style API that reads from any bound source transparently
  • Automatic parsing of JSON, TOML, YAML, INI, envfile, and Java properties config files via pluggable internal codecs
  • Live config-file watching with WatchConfig() and OnConfigChange() callbacks powered by fsnotify
  • Struct and map unmarshaling built on github.com/go-viper/mapstructure/v2, including embedded-struct squashing and custom decode hooks
  • Remote key/value store support (etcd, etcd3, Consul, Firestore, NATS) via a separate viper/remote submodule, with optional GPG-encrypted values through crypt
  • First-class pflag/Cobra flag binding through BindPFlag/BindPFlags, plus a pluggable FlagValue/FlagValueSet interface for other flag libraries

Common Use Cases

  • Loading a CLI application’s settings from a config file that can be overridden by flags and environment variables, in a well-defined precedence order
  • Building Cobra-based CLIs (doctl-style) where subcommand flags need to flow into the same configuration object as file- and env-based settings
  • Hot-reloading a long-running service’s configuration when its config file changes on disk, without a restart
  • Centralizing configuration for multiple deployment environments by combining defaults, a checked-in config file, and environment-variable overrides for secrets
  • Distributing configuration across a fleet of services via a shared etcd or Consul key, optionally GPG-encrypted

Under The Hood

Architecture

Viper centers on a single Viper struct (viper.go, ~2,170 lines) that owns per-source state — flags, env bindings, the parsed config-file map, remote-provider results, defaults, and explicit overrides — and resolves a requested key by walking those sources in precedence order (override > flag > env > config > key/value store > default) inside Get. A package-level v *Viper singleton (initialized in init()) backs the free-function API so viper.Get(...) and NewViper().Get(...) share the same code path. File discovery and format detection are delegated to a Finder interface (finder.go) operating over an afero.Fs abstraction rather than the OS filesystem directly, which is what lets tests and the viper.ReadConfig(io.Reader) path share logic with real file loads. Config-format parsing is isolated behind per-format codecs under internal/encoding/{json,toml,yaml,dotenv}, each implementing a small Codec interface, and encoding.go picks the right one from the file extension or an explicit SetConfigType call — so what breaks if you swap the YAML backend (as the project itself just did, moving to go.yaml.in/yaml/v3) is isolated to one codec file, not the whole library.

Tech Stack

Written in Go 1.23+, with a go.mod-declared dependency set that stays deliberately narrow: fsnotify for filesystem watch events, go-viper/mapstructure/v2 for reflection-based struct decoding, pelletier/go-toml/v2 and go.yaml.in/yaml/v3 for format parsing, spf13/afero for the virtual filesystem layer, spf13/cast for type coercion in the Get<Type> accessors, and spf13/pflag for POSIX-style flag binding. Remote key/value store support (etcd/etcd3/Consul/Firestore/NATS, via sagikazarmark/crypt) lives in a separate remote/ Go submodule with its own go.mod, keeping those heavier network dependencies out of the default import graph for consumers who only need local config files. The project also ships a Nix flake (flake.nix/flake.lock) for a reproducible contributor dev environment alongside a plain Makefile.

Code Quality

The root package has an extensive test suite — viper_test.go alone contains roughly 80 test functions covering precedence resolution, aliasing, sub-config extraction, remote providers, and edge cases in key delimiting — using the standard testing package with testify for assertions, plus dedicated _test.go files per concern (flags_test.go, finder_test.go, overrides_test.go, encoding_test.go). Each internal codec package carries its own codec_test.go. Errors are modeled as typed values (errors.go defines error types like FileLookupError and ConfigParseError, checked via errors.As in the README’s documented patterns) rather than raw string errors, and CI runs across js/wasm and aix/ppc64 build targets in addition to the standard matrix, which is unusually broad platform coverage for a configuration library. A make lint/make fmt pair enforces style, and the CI workflow gates on both build and lint jobs.

API Design Viper’s defining design choice is precedence-based key resolution over a case-insensitive, dot-delimited key space — callers write GetString("datastore.metric.host") once and get the right value whether it came from a flag, an env var, or a nested YAML block, without writing merge logic themselves. The tradeoff is an explicitly documented one: Viper does not deep-merge complex values (a fully-overridden key replaces the whole subtree), and concurrent read/write access is the caller’s responsibility to synchronize, both called out directly in the README rather than silently assumed. The package-level singleton keeps the zero-config case trivially easy (viper.Get(...) works with no setup) while viper.New() supports isolated instances for testing or multi-config scenarios — the README explicitly recommends the latter as best practice despite defaulting the former, which is an honest acknowledgment of a design tension rather than a hidden gotcha.

Used by 24 apps in this directory

TypeScript
66%
MIT

Jitsu

Data Engineering

5,110

Open-source, fully-scriptable data ingestion engine that streams events from web, apps, and APIs to any data warehouse in real time.

View details
89
Repo Health
79
Technical
66
Dependency
Built with
TypeScript 66%
Go 32%
Updated 1 weeks ago
Go
97%
MIT

Formance Ledger

Databases · Developer Tools · Invoicing Finance

1,448

The programmable open source core ledger for fintech — build money-moving applications with atomic multi-posting transactions, account-based modeling, and Numscript, a built-in DSL for financial logic.

View details
91
Repo Health
8
Technical
68
Dependency
Built with
Go 97%
Updated 1 weeks ago
TypeScript
51%
Other

Mattermost

Collaboration · Devops · Team Chat

39,418

Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.

View details
96
Repo Health
87
Technical
65
Dependency
Built with
TypeScript 51%
Go 40%
Updated 1 weeks ago
Go
53%
MIT

memos

Note Taking

64,031

Open-source, self-hosted note-taking built for quick capture — Markdown-native, lightweight, and fully yours.

View details
91
Repo Health
78
Technical
65
Dependency
Built with
Go 53%
TypeScript 46%
Updated 1 weeks ago
Go
81%
GPL 3.0

Navidrome

File Storage · Music Audio

24,331

Run your own personal Spotify — stream your entire music collection from any device, anywhere, forever.

View details
91
Repo Health
81
Technical
66
Dependency
Built with
Go 81%
JavaScript 15%
Updated 1 weeks ago
Go
75%
Other

Notifuse

Marketing

2,256

Open-source, self-hosted alternative to Mailchimp, Brevo, and Klaviyo — send newsletters and transactional emails without per-email pricing or vendor lock-in.

View details
83
Repo Health
80
Technical
65
Dependency
Built with
Go 75%
TypeScript 22%
Updated 1 weeks ago
Go
52%
Apache 2.0

opencloud

File Storage

6,218

Open source file management and collaboration platform that keeps your data under your control, no database required.

View details
86
Repo Health
80
Technical
68
Dependency
Built with
Go 52%
Gherkin 33%
PHP 11%
Updated 1 weeks ago
Go
79%
Apache 2.0

OpenMeter

Developer Tools · Invoicing Finance

2,401

Open-source metering and billing engine for AI, agentic, and DevTool monetization — ingest usage events in real time and turn them into accurate invoices automatically.

View details
87
Repo Health
81
Technical
66
Dependency
Built with
Go 79%
TypeScript 16%
Updated 1 weeks ago
Python
55%
Other

PostHog

Ab Testing Experimentation · Analytics · Developer Tools

40,397

The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.

View details
92
Repo Health
80
Technical
65
Dependency
Built with
Python 55%
TypeScript 36%
Updated 1 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers