Usage Guide

This guide covers the core functionalities of the godotenv library in detail, from loading files to writing them.

Loading Environment Variables

The most common function is godotenv.Load(). When called without arguments, it looks for a file named .env in the current working directory and loads its key-value pairs into the environment.

import "github.com/joho/godotenv"

func init() {
    // loads .env from the current directory
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }
}

Loading Specific Files

You can also provide one or more file paths to Load(). If multiple files are provided, they are loaded in order. If a variable is defined in multiple files, the value from the first file where it is found is used.

// loads config/.env.production and config/.env.secrets
err := godotenv.Load("config/.env.production", "config/.env.secrets")

Precedence: Load vs. Overload

Load() - Does Not Override

By default, godotenv.Load() will not override an environment variable that already exists in the environment. This is a safe default that prevents a local .env file from overriding production-configured variables.

// Suppose `API_KEY` is already set in the shell environment
// export API_KEY=existing_value

// .env file contains: API_KEY=new_value

godotenv.Load() // .env file is loaded

// os.Getenv("API_KEY") will still return "existing_value"

Overload() - Forces Override

If you need to ensure that the variables from your .env file take precedence, use godotenv.Overload(). This function works just like Load() but will override any existing environment variables.

// Suppose `API_KEY` is already set in the shell environment
// export API_KEY=existing_value

// .env file contains: API_KEY=new_value

godotenv.Overload() // .env file is loaded and overrides

// os.Getenv("API_KEY") will now return "new_value"

Reading Variables into a Map

If you prefer not to modify the global environment and want to handle the variables yourself, you can use godotenv.Read(). This function reads one or more .env files and returns the variables as a map[string]string.

var myEnv map[string]string
myEnv, err := godotenv.Read("credentials.env")
if err != nil {
    // handle error
}

s3Bucket := myEnv["S3_BUCKET"]

Parsing from In-Memory Sources

godotenv also supports parsing variables directly from an io.Reader or a string, which is useful for loading configuration from remote sources or other dynamic inputs.

From an io.Reader

Use godotenv.Parse() to read from any source that implements io.Reader.

// For example, reading from a string as an io.Reader
reader := strings.NewReader("KEY=value_from_reader")
parsedEnv, err := godotenv.Parse(reader)

fmt.Println(parsedEnv["KEY"]) // Outputs: value_from_reader

From a String or Byte Slice

Use godotenv.Unmarshal() to parse directly from a string or godotenv.UnmarshalBytes() for a []byte.

envString := "DB_HOST=remote.db\nDB_PORT=5432"

envMap, err := godotenv.Unmarshal(envString)

fmt.Println(envMap["DB_HOST"]) // Outputs: remote.db

Automatic Loading on Import (Autoload)

For maximum convenience, you can use the autoload package. By importing it with a blank identifier, your application will automatically call godotenv.Load() during its initialization.

package main

import (
    _ "github.com/joho/godotenv/autoload" // automatically loads .env
    "os"
)

func main() {
    // S3_BUCKET is now available via os.Getenv()
    s3Bucket := os.Getenv("S3_BUCKET")
}

Writing .env Files

godotenv can also serialize a map of environment variables into a valid .env file format.

Writing to a File

Use godotenv.Write() to save a map[string]string to a specified file. The keys will be sorted, and values will be properly quoted and escaped.

env := make(map[string]string)
env["KEY"] = "value"
env["COMMENT"] = "this has a # character"

err := godotenv.Write(env, "./.env.generated")
// .env.generated will contain:
// COMMENT="this has a # character"
// KEY="value"

Marshalling to a String

Use godotenv.Marshal() to get the .env formatted content as a string.

env, _ := godotenv.Read(".env")
content, err := godotenv.Marshal(env)

fmt.Println(content)