Godotenv vs Viper in Golang: Key Differences and When to Use Each
When working with Golang, managing configuration is crucial. Two popular libraries, Godotenv and Viper, offer different approaches. Let’s break down their differences and see which one fits your needs best.
In most Golang applications, environment variables are the go-to solution for managing configuration across different stages, such as development, staging, and production. They allow you to change settings without modifying the source code, making deployment smoother and reducing the risk of errors. Without environment variables, switching between environments can become a tedious and error-prone process.
For managing environment variables in Golang projects, two libraries are particularly popular: Godotenv and Viper. While both serve the same general purpose, they differ in features, flexibility, and ease of use.
Official GitHub Repositories:
Project Setup
Let’s set up a new Golang project and try them out.
mkdir golang-viper
cd golang-viper
code .Add go.mod file (use the same name as your project or any name you prefer).
go mod init golang-viperInstall the Godotenv and Viper packages:
go get github.com/spf13/viper
go get github.com/joho/godotenvUsing Viper
Create a new file main.go and add the following code:
package main
import (
"fmt"
"github.com/spf13/viper"
)
func main() {
viper.AddConfigPath("env") // Path to the config folder
viper.SetConfigType("env") // File type (env, yaml, or json)
viper.SetConfigName("app") // File name without extension
err := viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("fatal error config file: %w", err))
}
fmt.Println("DB_HOST from config:", viper.GetString("DB_HOST"))
fmt.Println("DB_PORT from config:", viper.GetString("DB_PORT"))
}Explanation:
viper.AddConfigPath("env"): Sets the directory where the config file is located. In this project, it’s inside theenvfolder.viper.SetConfigType("env"): Specifies the config file type (env,yaml, orjson). We’re using it.envhere.viper.SetConfigName("app")The config file name without extension (e.g.,app.env).viper.GetString("DB_HOST")→ Reads the value of the given key.
You can create env file like app.env or app.yaml or app.json.
Example app.env file (inside env/ folder):
DB_HOST=localhost
DB_PORT=5432Run the project:
go run .Output:
DB_HOST from config: localhost
DB_PORT from config: 5432Using Godotenv
Using Godotenv is simpler. Add the following code to your main.go:
package main
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
fmt.Println("dbHost:", dbHost)
fmt.Println("dbPort:", dbPort)
}Explanation:
godotenv.Load()→ Automatically loads variables from a.envfile into your environment.os.Getenv()→ Retrieves the value of the environment variable.
Example .env file:
DB_HOST=localhost
DB_PORT=5432Run the project:
go run . Output:
dbHost: localhost
dbPort: 5432Conclusion
Choosing between Godotenv and Viper depends on your project’s complexity:
- For simple projects, Godotenv is quick, minimal, and easy to use.
- For more complex needs — such as supporting multiple file formats (
.env,.yaml,.json), nested configs, and advanced options — Viper offers greater flexibility.
Both are excellent tools; pick the one that best fits your project requirements.
Enigma IT Bootcamp
Information Technology Company
For Recruitment:
📧: recruitment@enigmacamp.com
📞: +02127806212
For Partnership:
📞: +62 21 5081 2002 (ext. 838)
