DEV Community

Cover image for Difference between Godotenv and Viper in Golang
Jution Candra Kirana
Jution Candra Kirana

Posted on • Updated on

Difference between Godotenv and Viper in Golang

Hai everyone, long time no see… I would like to share important information according to the title above.

We know that using env on golang project is very important and useful because with env we can manage the configuration in different development environments like development, staging and production. Without env we will have trouble changing the development environment from development to staging and vice versa.

In the golang project there are 2 libraries that are often used, godotenv and viper.

GitHub logo joho / godotenv

A Go port of Ruby's dotenv library (Loads environment variables from .env files)

GoDotEnv CI Go Report Card

A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file).

From the original Library:

Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables.

But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped.

It can be used as a library (for loading in env for your own daemons etc.) or as a bin command.

There is test coverage and CI for both linuxish and Windows environments, but I make no guarantees about the bin version working on Windows.

Installation

As a library

go get
Enter fullscreen mode Exit fullscreen mode

GitHub logo spf13 / viper

Go configuration with fangs

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

Mentioned in Awesome Go run on repl.it

GitHub Workflow Status Join the chat at https://gitter.im/spf13/viper Go Report Card Go Version PkgGoDev

Go configuration with fangs!

Many Go projects are built using Viper including:

Install

go get github.com/spf13/viper
Enter fullscreen mode Exit fullscreen mode

Note: Viper uses Go Modules to manage dependencies.

What is Viper?

Viper is a complete configuration solution for Go applications including 12-Factor apps It is designed to work within an application, and can handle all types of configuration needs and formats. It supports:

  • setting defaults
  • reading from JSON, TOML, YAML, HCL, envfile and Java properties config files
  • live watching and re-reading of config files (optional)
  • reading from environment variables
  • reading from remote config systems (etcd or Consul), and watching changes
  • reading from command line flags
  • reading from…

Ok let's create the new project:

mkdir golang-viper
cd golang-viper
code .
Enter fullscreen mode Exit fullscreen mode

Add go.mod with the same name project or other:

go mod init golang-viper
Enter fullscreen mode Exit fullscreen mode

Install the godotenv and viper packages:

go get github.com/spf13/viper
go get github.com/joho/godotenv
Enter fullscreen mode Exit fullscreen mode

Using Viper 

Create a new file main.go and copy the following code:

package main

import (
 "fmt"
 "os"

 "github.com/spf13/viper"
)

func main() {
 viper.AddConfigPath("env")
 viper.SetConfigType("env")
 viper.SetConfigName("app")
 err := viper.ReadInConfig() // Find and read the config file
 if err != nil {             // Handle errors reading the config file
  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"))
}
Enter fullscreen mode Exit fullscreen mode

Explained:

  • viper.AddConfigPath("env") location env on your project, this project env in env directory.
  • viper.SetConfigType("env") type of env file, in viper we use env, yaml and json file. This project uses env file.
  • viper.SetConfigName("app") Name of the env file. This project env file will have the name app.env. You can create env file like app.env or app.yaml or app.json.

Next to read the configuration from env file you need to add viper.ReadConfig(). Next, to read the contents of the env we use viper.getString and put the key env file.

Below is the contents of the env file:

DB_HOST=localhost
DB_PORT=5432
Enter fullscreen mode Exit fullscreen mode

Run the project:

go run .
Enter fullscreen mode Exit fullscreen mode
➜  golang-viper go run . 
DB_HOST from config: localhost
DB_PORT from config: 5432
➜  golang-viper 
Enter fullscreen mode Exit fullscreen mode

Using Godotenv 

Using this library is very simple and easy, just put the code below on your configuration file:

package main

import (
    "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)
}
Enter fullscreen mode Exit fullscreen mode

Yes very easy with godotenv just put:

godotenv.Load()
Enter fullscreen mode Exit fullscreen mode

Run the project:

➜  golang-viper go run . 
dbHost: localhost
dbPort: 5432
➜  golang-viper
Enter fullscreen mode Exit fullscreen mode

Conclusion

  • Using godotenv and viper actually depends on the project being made, if it's a simple project using godotenv is the right choice.
  • The use of different env file options and we can flexibly set the viper option is the right one.

See you on next article...

Top comments (0)