I asked hundreds of Gophers what their favorite way to manage environment variables and configuration was for their Go projects.

Which Environment Variable Libraries do Golang engineers Prefer?


I asked hundreds of Gophers what their favorite way to manage environment variables and configuration was for their Go projects. There was much less consensus here than on other discussions I have had, so I’m going to call out a few different approaches for managing environment variables and configuration in your Golang projects.

Firstly, using no library was preferred by a few people, but it certainly isn’t the default. This makes sense, as reading in env vars, validating them and unmarshalling them onto a struct is a lot of boilerplate and I think it makes sense to explore libraries for this.

This library from ArdanLabs seems popular. I have not used this, but I can see why it’s popular from the docs. It’s fully featured and does everything you would want. I’ll be giving this a go shortly!

Secondly, https://github.com/joho/godotenv is popular. I have used this one a lot. The approach of this library (and the name) exists in every language I have worked with in recent years so it makes sense that folks coming to Go from other languages would find this one and like the patterns. Here’s a simple example from the README:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    // Get the PORT environment variable
    port := os.Getenv("PORT")
    fmt.Println("Port:", port)
}

Finally, https://github.com/caarlos0/env. Again, seems fully featured and the usage matches the above patterns:

package main

import (
    "fmt"
    "log"

    "github.com/caarlos0/env/v6"
)

type Config struct {
    Port int `env:"PORT" envDefault:"8080"`
}

func main() {
    cfg := Config{}
    if err := env.Parse(&cfg); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", cfg)
}

My take: One significant advantage of using godotenv is its familiarity to developers from other languages, making it easier for them to adopt and use. This can be especially beneficial in a development team where members have varied software backgrounds. The consistency of patterns across different languages can help in reducing the learning curve, thus speeding up the onboarding process and the time to productivity.

On the other hand, the conf library by ArdanLabs is well-regarded for its comprehensive feature set. It seems versatile, making it a great choice for complex applications that require a more structured configuration management approach. Its ability to handle multiple configuration sources looks like it could work well for larger projects.

Similarly, env by caarlos0 offers a straightforward and efficient way to handle environment variables. Its simplicity and effectiveness make it a great choice for many projects, and its familiar pattern helps in maintaining readability across your codebases.

My advice is to pick one and stick with it at your company to maintain consistency. Consistency in your choice of tools and libraries ensures that your team can collaborate more effectively, share knowledge easily, and maintain a codebase easily.

Evaluate the specific needs of your project and team, and choose the library that best fits those needs. Whether you prioritize familiarity, feature set, or simplicity, any of these libraries will serve you well in managing environment variables in Go.

Happy coding!