30,508
stars
+8+11+26
2,214
forks
–
watchers
–
prs
–
issues
–
releases
–
discussions
README
Viper v2 Feedback
Viper is heading towards v2 and we would love to hear what _you_ would
like to see in it. Share your thoughts here:
https://forms.gle/R6faU74qPRPAzchZ9
Thank you!
!viper logo
!Go Version
Go configuration with fangs!
Many Go projects are built using Viper including:
Hugo
EMC RexRay
Imgur’s Incus
Nanobox/Nanopack
Docker Notary
BloomApi
doctl
Clairctl
Mercure
Meshery
Bearer
Coder
Vitess
Install
shell
go get github.com/spf13/viper
NOTE Viper uses Go Modules to manage dependencies.
Why use Viper?
Viper is a complete configuration solution for Go applications including
12-Factor apps. It is designed to
work within any application, and can handle all types of configuration needs
and formats. It supports:
setting defaults
setting explicit values
reading config files
dynamic discovery of config files across multiple locations
reading from environment variables
reading from remote systems (e.g. Etcd or Consul)
reading from command line flags
reading from buffers
live watching and updating configuration
aliasing configuration keys for easy refactoring
Viper can be thought of as a registry for all of your applications'
configuration needs.
Putting Values in Viper
Viper can read from multiple configuration sources and merges them together
into one set of configuration keys and values.
Viper uses the following precedence for merging:
explicit call to Set
flags
environment variables
config files
external key/value stores
defaults
NOTE Viper configuration keys are case insensitive.
Reading Config Files
Viper requires minimal configuration to load config files. Viper currently supports:
JSON
TOML
YAML
INI
envfile
Java Propeties
A single Viper instance only supports a single configuration file, but multiple
paths may be searched for one.
Here is an example of how to use Viper to search for and read a configuration
file. At least one path should be provided where a configuration file is
expected.
go
// Name of the config file without an extension (Viper will intuit the type
// from an extension on the actual file)
viper.SetConfigName("config")
// Add search paths to find the file
viper.AddConfigPath("/etc/appname/")
viper.AddConfigPath("$HOME/.appname")
viper.AddConfigPath(".")
// Find and read the config file
err := viper.ReadInConfig()
// Handle errors
if err != nil {
panic(fmt.Errorf("fatal error config file: %w", err))
}
You can handle the specific case where no config file is found.
go
var fileLookupError viper.FileLookupError
if err := viper.ReadInConfig(); err != nil {
if errors.As(err, &fileLookupError) {
// Indicates an explicitly set config file is not found (such as with
// using viper.SetConfigFile) or that no config file was found in
// any search path (such as when using viper.AddConfigPath)
} else {
// Config file was found but another error was produced
}
}
// Config file found and successfully