Load environment variables from `.env` or `io.Reader` in Go.

Overview

gotenv

Build Status Coverage Status Go Report Card GoDoc

Load environment variables from .env or io.Reader in Go.

Usage

Put the gotenv package on your import statement:

import "github.com/subosito/gotenv"

To modify your app environment variables, gotenv expose 2 main functions:

  • gotenv.Load
  • gotenv.Apply

By default, gotenv.Load will look for a file called .env in the current working directory.

Behind the scene, it will then load .env file and export the valid variables to the environment variables. Make sure you call the method as soon as possible to ensure it loads all variables, say, put it on init() function.

Once loaded you can use os.Getenv() to get the value of the variable.

Let's say you have .env file:

APP_ID=1234567
APP_SECRET=abcdef

Here's the example of your app:

package main

import (
	"github.com/subosito/gotenv"
	"log"
	"os"
)

func init() {
	gotenv.Load()
}

func main() {
	log.Println(os.Getenv("APP_ID"))     // "1234567"
	log.Println(os.Getenv("APP_SECRET")) // "abcdef"
}

You can also load other than .env file if you wish. Just supply filenames when calling Load(). It will load them in order and the first value set for a variable will win.:

gotenv.Load(".env.production", "credentials")

While gotenv.Load loads entries from .env file, gotenv.Apply allows you to use any io.Reader:

gotenv.Apply(strings.NewReader("APP_ID=1234567"))

log.Println(os.Getenv("APP_ID"))
// Output: "1234567"

Both gotenv.Load and gotenv.Apply DO NOT overrides existing environment variables. If you want to override existing ones, you can see section below.

Environment Overrides

Besides above functions, gotenv also provides another functions that overrides existing:

  • gotenv.OverLoad
  • gotenv.OverApply

Here's the example of this overrides behavior:

os.Setenv("HELLO", "world")

// NOTE: using Apply existing value will be reserved
gotenv.Apply(strings.NewReader("HELLO=universe"))
fmt.Println(os.Getenv("HELLO"))
// Output: "world"

// NOTE: using OverApply existing value will be overridden
gotenv.OverApply(strings.NewReader("HELLO=universe"))
fmt.Println(os.Getenv("HELLO"))
// Output: "universe"

Throw a Panic

Both gotenv.Load and gotenv.OverLoad returns an error on something wrong occurred, like your env file is not exist, and so on. To make it easier to use, gotenv also provides gotenv.Must helper, to let it panic when an error returned.

err := gotenv.Load(".env-is-not-exist")
fmt.Println("error", err)
// error: open .env-is-not-exist: no such file or directory

gotenv.Must(gotenv.Load, ".env-is-not-exist")
// it will throw a panic
// panic: open .env-is-not-exist: no such file or directory

Another Scenario

Just in case you want to parse environment variables from any io.Reader, gotenv keeps its Parse and StrictParse function as public API so you can use that.

// import "strings"

pairs := gotenv.Parse(strings.NewReader("FOO=test\nBAR=$FOO"))
// gotenv.Env{"FOO": "test", "BAR": "test"}

pairs, err := gotenv.StrictParse(strings.NewReader(`FOO="bar"`))
// gotenv.Env{"FOO": "bar"}

Parse ignores invalid lines and returns Env of valid environment variables, while StrictParse returns an error for invalid lines.

Notes

The gotenv package is a Go port of dotenv project with some additions made for Go. For general features, it aims to be compatible as close as possible.

Comments
  • Marshal

    Marshal

    Adding convenience methods for marshalling unmarshalling and writing envs to a file. I've also added some performance tweaks, you can review each commit separately.

    opened by luisdavim 7
  • multiline ENV variable?

    multiline ENV variable?

    Do you have any plans to support multiline ENV variables? linePattern regex already supports it, but bufio.NewScanner(r) produces variable splitted by new line separator and makes it invalid before linePattern applied.

    opened by sergolius 3
  • bug: eliminating any combinations of `$1` or `$2` from any environment variables on retrieve.

    bug: eliminating any combinations of `$1` or `$2` from any environment variables on retrieve.

    Getting live environment variables that contain a $1 or $2 in a legitimate string is dropped from the variable

    This combination can happen in a legitimate environment variable (like a password)

    The line that causes the drop is here https://github.com/subosito/gotenv/blob/27d387744383d355a04cdfada1736405440c595e/gotenv.go#L167

    Trying to understand why this would be getting dropped in this way.

    opened by stevehebert 1
  • Support = within double-quoted strings

    Support = within double-quoted strings

    This change enables e.g. PEM-encoded keys to be parsed by gotenv, which is supported by other .env implementations.

    It also simplifies parseVal, as due to bufio's ScanLines splitting, "\n" will never be encountered in a passed-in string.

    opened by Deiz 1
  • Documentation incorrect for return values of StrictParse

    Documentation incorrect for return values of StrictParse

    The documentation for the StrictParse method is done incorrectly. The return values are swapped between the actual error and the map returned. It is currently documented as

    err, pairs = gotenv.StrictParse(strings.NewReader(`FOO="bar"`))
    

    which should have been below as per the function definition

    pairs, err = gotenv.StrictParse(strings.NewReader(`FOO="bar"`))
    

    The swapped order could be potentially confusing, but not a major one.

    opened by inianv 1
  • equal sign (=) character support

    equal sign (=) character support

    I'm trying to add a cert to .env file like this: CERT: "-----BEGIN CERTIFICATE-----\nMIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLh==........”

    but it doesn't works if there is equal sign = character in the value

    Any suggestion?

    opened by wiskarindra 1
  • Unclear specification in Usage instructions

    Unclear specification in Usage instructions

    I found the Usage section in instructions to be a bit unclear:

    Store your configuration to .env file on your root directory of your project

    This may not always be the case. As many go projects are made up of multiple executables. In my specific scenario: I have a rootdir and the subsequent directories rootdir/cmd/someWebService and rootdir/cmd/clock, where clock is a simple ticker for the web-service.

    As I've come to understand after messing around with gotenv for a while, what it actually does is reading files in directories relative to the file taking use of gotenv.Load()

    Coming back to my scenario, I have to specify a relative path in gotenv.Load(...) for each of my executables. This is honestly not actually a bad thing, as it allows for more flexibility in my go code and file/folder structure. The point I'm trying to make is rather this: The Usage instructions doesn't specify in a good manner where it reads from.

    • Thank you
    opened by Stektpotet 1
  • OverLoad: local variables do not override environment variables

    OverLoad: local variables do not override environment variables

    When using override functions like OverLoad local variables do not override environment variables anymore, since #12.

    Example 1

    $ export A="fromEnv"
    $ cat .env
    A="fromFile"
    B="$A"
    

    Expected Behaviour

    After using OverLoad, variable B should have value fromFile.

    Actual Behaviour

    Variable B has value fromEnv.

    Example 2: Recursive variable expansion

    $ export B="fromEnv"
    $ cat .env
    A="$B$C"
    B="fromFile"
    C="fnord"
    

    What is the expected behaviour, when a reference is resolved before its definition? I would argue it should be fromEnv, since gotenv evaluates environment files line by line.

    opened by 5nord 0
  • Unexpected behaviour when referencing variables

    Unexpected behaviour when referencing variables

    When resolving variable references definitions in environment file take precedence over environment variables.

    Example

    $ export A="fromEnv"
    $ cat .env
    A="fromFile"
    B="$A"
    

    Expected behavior

    After loading environment file, variable B should have value fromEnv.

    Current behavior

    After loading environment file, variable B has value fromFile

    opened by 5nord 0
  • more consistent line splitting

    more consistent line splitting

    change the scanner to split lines according to expected behavior, e.g: split lines on LF, CR or CRLF

    remove need for extra function to guess that after the facts

    opened by LeGEC 1
  • Ignore missing files and options

    Ignore missing files and options

    I wanted to be able to ignore missing .env file, because I sometimes directly load environment variable without using the .env file (docker, or else ...).

    So I wonder whether this package is open to add such options or if you want to keep it simple stupid ? Meaning that I will have to check if the files exists myself before loading.

    Therefore I'd like to propose a extra LoadWithOptions function that allows on to define options such as IgnoreMissingFiles.

    opened by jooola 1
  • ENV Reset

    ENV Reset

    Firstly, thank you for the library. It works beautifully!

    The one thing I find missing is a reset option with this library. In testing I've found once the environment is set during testing it is impossible to reset the environment with the tool that modified it. I can write my own code for the testing but it would be nice to just call gotenv.Reset(). 👼

    opened by runeimp 3
Owner
Alif Rachmawadi
Alif Rachmawadi
Don't get surprised by your environment variables.

checkenv Don't get surprised by your environment variables. Rationale At Bugout, we configure our applications using environment variables. This follo

Bugout.dev 2 Dec 20, 2021
Forklift: an API application developed with go that enables virtual server migration from vcenter virtualization environment to openstack environment

What is the Forklift? Forklift is an API application developed with go that enables virtual server migration from vcenter virtualization environment t

Ali 3 Jan 14, 2022
Optimized bit-level Reader and Writer for Go.

bitio Package bitio provides an optimized bit-level Reader and Writer for Go. You can use Reader.ReadBits() to read arbitrary number of bits from an i

András Belicza 205 Dec 1, 2022
Minimalist and opinionated feed reader

Miniflux 2 Miniflux is a minimalist and opinionated feed reader: Written in Go (Golang) Works only with Postgresql Doesn't use any ORM Doesn't use any

Miniflux 4.4k Jan 3, 2023
A bit reader tool written in golang

A bit reader tool written in golang

Potter XU 0 Dec 12, 2021
:runner:runs go generate recursively on a specified path or environment variable and can filter by regex

Package generate Package generate runs go generate recursively on a specified path or environment variable like $GOPATH and can filter by regex Why wo

Go Playgound 28 Sep 27, 2022
Manage internal technical documentation that is enriched with live data accreted from your environment.

Manage internal technical documentation that is enriched with live data accreted from your environment.

Daniel Tedman 0 Jan 3, 2023
Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables to be loaded from the .env file.

genv Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables

Şakir Şensoy 31 Dec 21, 2022
A Go (golang) environment loader (which loads env vars from a .env file)

A Go (golang) environment loader (which loads env vars from a .env file)

Bendt Indonesia 0 Feb 8, 2022
A Go port of Ruby's dotenv library (Loads environment variables from `.env`.)

GoDotEnv 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

John Barton 5.7k Jan 5, 2023
formicidate is a small tool for Go application can update the value of environment variables in a .env file with code

formicidae Update .env files in Go with code. What is fomicidae? formicidate is a small tool for Go application. You can update the value of environme

akuma 0 Jan 23, 2022
Dotnet-appsettings-env - Convert .NET appsettings.json file to Kubernetes, Docker and Docker-Compose environment variables

dotnet-appsettings-env Convert .NET appsettings.json file to Kubernetes, Docker

Daniel Dias de Assumpção 18 Dec 30, 2022
Dotnet-appsettings-env - Convert .NET appsettings.json file to Kubernetes, Docker and Docker-Compose environment variables

dotnet-appsettings-env Convert .NET appsettings.json file to Kubernetes, Docker

Daniel Dias de Assumpção 1 Feb 16, 2022
GoLobby DotEnv is a lightweight package for loading dot env (.env) files into structs for Go projects

DotEnv GoLobby DotEnv is a lightweight package for loading dot env (.env) files into structs for Go projects Documentation Supported Versions It requi

GoLobby 23 Dec 30, 2022
Tmpl - A tool to apply variables from cli, env, JSON/TOML/YAML files to templates

tmpl allows to apply variables from JSON/TOML/YAML files, environment variables or CLI arguments to template files using Golang text/template and functions from the Sprig project.

krako 2 Nov 14, 2022
OcppManager-go - A library for dynamically managing OCPP configuration (variables). It can read, update, and validate OCPP variables.

?? ocppManager-go A library for dynamically managing OCPP configuration (variables). It can read, update, and validate OCPP variables. Currently, only

Blaž 0 Jan 3, 2022
`runenv` create gcloud run deploy `--set-env-vars=` option and export shell environment from yaml file.

runenv runenv create gcloud run deploy --set-env-vars= option and export shell environment from yaml file. Motivation I want to manage Cloud Run envir

sonatard 0 Feb 10, 2022
✨Clean and minimalistic environment configuration reader for Golang

Clean Env Minimalistic configuration reader Overview This is a simple configuration reading tool. It just does the following: reads and parses configu

Ilya Kaznacheev 857 Jan 8, 2023
Simple lib to parse environment variables to structs

env Simple lib to parse envs to structs in Go. Example A very basic example: package main import ( "fmt" "time" // if using go modules "github.c

Carlos Alexandro Becker 3.1k Jan 9, 2023