godotenv README

The project's README from github.com/joho/godotenv. As one markdown file: README.md.

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 github.com/joho/godotenv

as a tool dependency:

go >= 1.24

go get -tool github.com/joho/godotenv/cmd/godotenv

or if you want to use it as a bin command

go install github.com/joho/godotenv/cmd/godotenv@latest

Usage

Add your application configuration to your .env file in the root of your project:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE

Then in your Go app you can do something like

package main

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

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

  s3Bucket := os.Getenv("S3_BUCKET")
  secretKey := os.Getenv("SECRET_KEY")

  // now do something with s3 or whatever
}

If you're even lazier than that, you can just take advantage of the autoload package which will read in .env on import

import _ "github.com/joho/godotenv/autoload"

While .env in the project root is the default, you don't have to be constrained, both examples below are 100% legit

godotenv.Load("somerandomfile")
godotenv.Load("filenumberone.env", "filenumbertwo.env")

If you want to be really fancy with your env file you can do comments and exports (below is a valid env file)

# I am a comment and that is OK
SOME_VAR=someval
FOO=BAR # comments at line end are OK too
export BAR=BAZ

Or finally you can do YAML(ish) style

FOO: bar
BAR: baz

as a final aside, if you don't want godotenv munging your env you can just get a map back instead

var myEnv map[string]string
myEnv, err = godotenv.Read()

s3Bucket := myEnv["S3_BUCKET"]

... or from an io.Reader instead of a local file

reader := getRemoteFile()
myEnv, err := godotenv.Parse(reader)

... or from a string if you so desire

content := getRemoteFileContent()
myEnv, err := godotenv.Unmarshal(content)

Variable name compatibility

Ruby's dotenv only allows [A-Za-z0-9_.] in key names, while Node's dotenv also permits -. godotenv has matched the Node charset since v1.4.0, so keys like MY-VAR parse cleanly here and in Node but will error under Ruby's dotenv.

Precedence & Conventions

Existing envs take precedence of envs that are loaded later.

The convention for managing multiple environments (i.e. development, test, production) is to create an env named {YOURAPP}_ENV and load envs in this order:

env := os.Getenv("FOO_ENV")
if "" == env {
  env = "development"
}

godotenv.Load() // The Original .env
godotenv.Load(".env." + env)
if "test" != env {
  godotenv.Load(".env.local")
}
godotenv.Load(".env." + env + ".local")

If you need to, you can also use godotenv.Overload() to defy this convention and overwrite existing envs instead of only supplanting them. Use with caution.

Command Mode

Assuming you've installed the command as above and you've got $GOPATH/bin in your $PATH

godotenv -f /some/path/to/.env some_command with some args

If you don't specify -f it will fall back on the default of loading .env in PWD

By default, it won't override existing environment variables; you can do that with the -o flag.

Writing Env Files

Godotenv can also write a map representing the environment to a correctly-formatted and escaped file

env, err := godotenv.Unmarshal("KEY=value")
err := godotenv.Write(env, "./.env")

... or to a string

env, err := godotenv.Unmarshal("KEY=value")
content, err := godotenv.Marshal(env)

Contributing

Contributions are welcome, but with some caveats.

This library has been declared feature complete (see #182 for background) and will not be accepting issues or pull requests adding new functionality or breaking the library API.

Contributions would be gladly accepted that:

code changes without tests and references to peer dotenv implementations will not be accepted

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Releases

Releases should follow Semver though the first couple of releases are v1 and v1.1.

Use annotated tags for all releases. Example git tag -a v1.2.1

Who?

The original library dotenv was written by Brandon Keepers, and this port was done by John Barton based off the tests/fixtures in the original library.

godotenv (joho/godotenv)

Searching Database…

10.7K ·GitHub
What is this?It's a Go port of Ruby's dotenv: a library and CLI that loads environment variables from a .env file into your process environment when the app bootstraps.
Is it a library or a command-line tool?Both. Import it as a Go library to load env vars for your own daemons and apps, or install it as a bin command that loads .env and runs your program.
How do I start using it in my Go app?Add it as a tool dependency, put your configuration in a .env file in your project root, then load it in your Go app — or import the autoload package and .env is read automatically.
Do I need a specific Go version for it?Go 1.24 or newer is the only requirement; beyond that the library has no external dependencies.
Will .env values override variables I already have set in my environment?No — existing environment variables always take precedence over loaded .env values. Call godotenv.Overload() (or pass -o in command mode) if you really want to overwrite them.
Does the command version work on Windows?The library itself is CI-tested on both Linux-ish and Windows environments, but the author explicitly makes no guarantees about the bin command on Windows.
What can I put in my .env file?Standard KEY=value lines, plus comments, export prefixes, and even YAML-ish style are all accepted as valid env file syntax.
Can I load env vars from somewhere other than a .env in the project root?Yes — you can point it at a custom path, load from an io.Reader or a string, or get everything back as a map instead of mutating the environment.
Can godotenv write .env files too, or only read them?It writes too: godotenv can serialize a map representing your environment to a correctly-formatted and escaped .env file, or to a string.
Is the project still being actively developed?It's declared feature complete: bug fixes, closer compatibility with mainline dotenv implementations and ecosystem upkeep are accepted, but new features and API-breaking changes are not.
What are similar projects?phpdotenv, dotenv, yq, gvm, caire, chezmoi, lazygit, mise
Creator
joho
Size
0.2 MB
Stars
10.7K
Age
13y
Commits · 90 Days