env

package module
v2.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2026 License: MIT Imports: 12 Imported by: 0

README

goforj/env logo

Typed environment variables for Go - safe defaults, app env helpers, and zero-ceremony configuration.

Go Reference Go Test Go version Latest tag Go Report Card

Features

env provides strongly-typed access to environment variables with predictable fallbacks. Eliminate string parsing, centralize app environment checks, and keep configuration boring. Designed to feel native to Go - and invisible when things are working.

  • Strongly typed getters - int, bool, float, duration, slices, maps
  • Safe fallbacks - never panic, never accidentally empty
  • Application environment helpers - local, staging, production
  • Minimal dependencies - Pure Go, lightweight, minimal surface area
  • Framework-agnostic - works with any Go app
  • Enum validation - constrain values with allowed sets
  • Predictable behavior - no magic, no global state surprises
  • Composable building block - ideal for config structs and startup wiring

Why env?

Accessing environment variables in Go often leads to:

  • Repeated parsing logic
  • Unsafe string conversions
  • Inconsistent defaults
  • Scattered app environment checks

env solves this by providing typed accessors with fallbacks, so configuration stays boring and predictable.

Installation

go get github.com/goforj/env/v2

Quickstart

package main

import (
	"log"
	"time"

	"github.com/goforj/env/v2"
)

func init() {
	if err := env.Load(); err != nil {
		log.Fatalf("load env: %v", err)
	}
}

func main() {
    addr := env.Get("ADDR", "127.0.0.1:8080")
    debug := env.GetBool("DEBUG", "false")
    timeout := env.GetDuration("HTTP_TIMEOUT", "5s")
    
    env.Dump(addr, debug, timeout)
    // #string "127.0.0.1:8080"
    // #bool false
    // #time.Duration 5s
    
    env.Dump("container?", env.IsContainer())
    // #string "container?"
    // #bool false
}

Scoped prefixes

Use Scope when a group of related settings share a common prefix and may also expose named child configs.

package main

import (
	"os"

	"github.com/goforj/env/v2"
)

func main() {
	_ = os.Setenv("STORAGE_DRIVER", "local")
	_ = os.Setenv("STORAGE_ROOT", "storage/app/private")
	_ = os.Setenv("STORAGE_PUBLIC_DRIVER", "local")
	_ = os.Setenv("STORAGE_PUBLIC_ROOT", "storage/app/public")
	_ = os.Setenv("STORAGE_AVATARS_DRIVER", "s3")
	_ = os.Setenv("STORAGE_AVATARS_BUCKET", "my-bucket")
	_ = os.Setenv("STORAGE_AVATARS_REGION", "us-east-1")

	storage := env.WithPrefix("STORAGE")

	// Root/default config reads STORAGE_* keys.
	driver := storage.Get("DRIVER", "local")
	root := storage.Get("ROOT", "storage/app/private")

	public := storage.Child("PUBLIC")

	// Child scopes compose STORAGE_<NAME>_* keys.
	publicDriver := public.Get("DRIVER", "local")
	publicRoot := public.Get("ROOT", "storage/app/public")

	// ChildNames discovers named children while ignoring root keys.
	names := storage.ChildNames([]string{
		"DRIVER",
		"ROOT",
		"BUCKET",
		"REGION",
	})

	env.Dump(driver, root, publicDriver, publicRoot, names)
	// #string "local"
	// #string "storage/app/private"
	// #string "local"
	// #string "storage/app/public"
	// #[]string [
	//  0 => "AVATARS" #string
	//  1 => "PUBLIC" #string
	// ]
}
Full kitchen-sink example

See examples/kitchensink/main.go for a runnable program that exercises almost every helper (env loading, typed getters, must-getters, runtime + container detection, and the env.Dump wrapper) with deterministic godump output.

Environment loading

Load loads env files in this order:

  • .env
  • .env.local, .env.staging, or .env.production, based on APP_ENV (local by default)
  • .env.testing when running under tests
  • .env.host when running on the host or DinD

Later files override earlier ones. Repeated calls are no-ops.

Container detection

Check True when Notes
IsDocker /.dockerenv or Docker cgroup markers Generic Docker container
IsDockerInDocker /.dockerenv and docker.sock Inner DinD container
IsDockerHost docker.sock present, no container cgroups Host or DinD outer acting as host
IsContainer Any common container signals (Docker, containerd, kube env/cgroup) General container detection
IsKubernetes KUBERNETES_SERVICE_HOST or kubepods cgroup Inside a Kubernetes pod

Runnable examples

Every function has a corresponding runnable example under ./examples.

These examples are generated directly from the documentation blocks of each function, ensuring the docs and code never drift. These are the same examples you see here in the README and GoDoc.

An automated test executes every example to verify it builds and runs successfully.

This guarantees all examples are valid, up-to-date, and remain functional as the API evolves.

Environment file loading

This package uses github.com/joho/godotenv for .env file loading.

It is intentionally composed into the runtime detection and APP_ENV model rather than reimplemented.

Philosophy

env is part of the GoForj toolchain - a collection of focused, composable packages designed to make building Go applications satisfying.

No magic. No globals. No surprises.

API Index
Group Functions
Application environment GetAppEnv IsAppEnv IsAppEnvLocal IsAppEnvLocalOrStaging IsAppEnvProduction IsAppEnvStaging IsAppEnvTesting IsAppEnvTestingOrLocal SetAppEnv SetAppEnvLocal SetAppEnvProduction SetAppEnvStaging SetAppEnvTesting
Container detection IsContainer IsDocker IsDockerHost IsDockerInDocker IsHostEnvironment IsKubernetes
Debugging Dump
Environment loading IsEnvLoaded Load LoadEnvFileIfExists Reload
Other Key
Runtime Arch IsBSD IsContainerOS IsLinux IsMac IsUnix IsWindows OS
Typed getters Child ChildNames Get GetBool GetDuration GetEnum GetFloat GetInt GetInt64 GetMap GetMapInt GetSlice GetUint GetUint64 MustGet MustGetBool MustGetInt WithPrefix

Application environment

GetAppEnv

GetAppEnv returns the current APP_ENV (empty string if unset).

Example: simple retrieval

_ = os.Setenv("APP_ENV", "staging")
env.Dump(env.GetAppEnv())
// #string "staging"
IsAppEnv

IsAppEnv checks if APP_ENV matches any of the provided environments.

Example: match any allowed environment

_ = os.Setenv("APP_ENV", "staging")
env.Dump(env.IsAppEnv(env.Production, env.Staging))
// #bool true

Example: unmatched environment

_ = os.Setenv("APP_ENV", "local")
env.Dump(env.IsAppEnv(env.Production, env.Staging))
// #bool false
IsAppEnvLocal

IsAppEnvLocal checks if APP_ENV is "local".

_ = os.Setenv("APP_ENV", env.Local)
env.Dump(env.IsAppEnvLocal())
// #bool true
IsAppEnvLocalOrStaging

IsAppEnvLocalOrStaging checks if APP_ENV is either "local" or "staging".

_ = os.Setenv("APP_ENV", env.Local)
env.Dump(env.IsAppEnvLocalOrStaging())
// #bool true
IsAppEnvProduction

IsAppEnvProduction checks if APP_ENV is "production".

_ = os.Setenv("APP_ENV", env.Production)
env.Dump(env.IsAppEnvProduction())
// #bool true
IsAppEnvStaging

IsAppEnvStaging checks if APP_ENV is "staging".

_ = os.Setenv("APP_ENV", env.Staging)
env.Dump(env.IsAppEnvStaging())
// #bool true
IsAppEnvTesting

IsAppEnvTesting reports whether APP_ENV is "testing" or the process looks like go test.

Example: APP_ENV explicitly testing

_ = os.Setenv("APP_ENV", env.Testing)
env.Dump(env.IsAppEnvTesting())
// #bool true

Example: no test markers

_ = os.Unsetenv("APP_ENV")
env.Dump(env.IsAppEnvTesting())
// #bool false (outside of test binaries)
IsAppEnvTestingOrLocal

IsAppEnvTestingOrLocal checks if APP_ENV is "testing" or "local".

_ = os.Setenv("APP_ENV", env.Testing)
env.Dump(env.IsAppEnvTestingOrLocal())
// #bool true
SetAppEnv

SetAppEnv sets APP_ENV to a supported value.

Example: set a supported environment

_ = env.SetAppEnv(env.Staging)
env.Dump(env.GetAppEnv())
// #string "staging"
SetAppEnvLocal

SetAppEnvLocal sets APP_ENV to "local".

_ = env.SetAppEnvLocal()
env.Dump(env.GetAppEnv())
// #string "local"
SetAppEnvProduction

SetAppEnvProduction sets APP_ENV to "production".

_ = env.SetAppEnvProduction()
env.Dump(env.GetAppEnv())
// #string "production"
SetAppEnvStaging

SetAppEnvStaging sets APP_ENV to "staging".

_ = env.SetAppEnvStaging()
env.Dump(env.GetAppEnv())
// #string "staging"
SetAppEnvTesting

SetAppEnvTesting sets APP_ENV to "testing".

_ = env.SetAppEnvTesting()
env.Dump(env.GetAppEnv())
// #string "testing"

Container detection

IsContainer

IsContainer detects common container runtimes (Docker, containerd, Kubernetes, Podman).

Example: host vs container

env.Dump(env.IsContainer())
// #bool true  (inside most containers)
// #bool false (on bare-metal/VM hosts)
IsDocker

IsDocker reports whether the current process is running in a Docker container.

Example: typical host

env.Dump(env.IsDocker())
// #bool false (unless inside Docker)
IsDockerHost

IsDockerHost reports whether this container behaves like a Docker host.

env.Dump(env.IsDockerHost())
// #bool true  (when acting as Docker host)
// #bool false (for normal containers/hosts)
IsDockerInDocker

IsDockerInDocker reports whether we are inside a Docker-in-Docker environment.

env.Dump(env.IsDockerInDocker())
// #bool true  (inside DinD containers)
// #bool false (on hosts or non-DinD containers)
IsHostEnvironment

IsHostEnvironment reports whether the process is running outside any container or orchestrated runtime.

env.Dump(env.IsHostEnvironment())
// #bool true  (on bare-metal/VM hosts)
// #bool false (inside containers)
IsKubernetes

IsKubernetes reports whether the process is running inside Kubernetes.

env.Dump(env.IsKubernetes())
// #bool true  (inside Kubernetes pods)
// #bool false (elsewhere)

Debugging

Dump

Dump is a convenience function that calls godump.Dump.

Example: integers

nums := []int{1, 2, 3}
env.Dump(nums)
// #[]int [
//   0 => 1 #int
//   1 => 2 #int
//   2 => 3 #int
// ]

Example: multiple values

env.Dump("status", map[string]int{"ok": 1, "fail": 0})
// #string "status"
// #map[string]int [
//   "fail" => 0 #int
//   "ok"   => 1 #int
// ]

Environment loading

IsEnvLoaded

IsEnvLoaded reports whether Load or LoadEnvFileIfExists was executed in this process.

env.Dump(env.IsEnvLoaded())
// #bool true  (after Load)
// #bool false (otherwise)
Load

Load loads .env with optional layering for .env.local/.env.staging/.env.production, plus .env.testing/.env.host when present. It only applies once per process; subsequent calls return without reloading because the result is cached. Use Reload to re-read env files after the first load.

Example: test-specific env file

tmp, _ := os.MkdirTemp("", "envdoc")
_ = os.WriteFile(filepath.Join(tmp, ".env.testing"), []byte("PORT=9090\nENV_DEBUG=0"), 0o644)
_ = os.Chdir(tmp)
_ = os.Setenv("APP_ENV", env.Testing)

_ = env.Load()
env.Dump(os.Getenv("PORT"))
// #string "9090"

Example: default .env on a host

_ = os.WriteFile(".env", []byte("SERVICE=api\nENV_DEBUG=3"), 0o644)
_ = env.Load()
env.Dump(os.Getenv("SERVICE"))
// #string "api"
LoadEnvFileIfExists

LoadEnvFileIfExists is a compatibility alias for Load.

_ = env.LoadEnvFileIfExists()
Reload

Reload re-applies the same layered env loading as Load, even if Load already ran earlier in the same process.

Example: refresh changed env files

_ = os.WriteFile(".env", []byte("SERVICE=api"), 0o644)
_ = env.Load()
_ = os.WriteFile(".env", []byte("SERVICE=worker"), 0o644)
_ = env.Reload()
env.Dump(os.Getenv("SERVICE"))
// #string "worker"

Other

Key

Key builds the fully qualified environment key for key within the scope.

Runtime

Arch

Arch returns the CPU architecture the binary is running on.

Example: print GOARCH

env.Dump(env.Arch())
// #string "amd64"
// #string "arm64"
IsBSD

IsBSD reports whether the runtime OS is any BSD variant.

env.Dump(env.IsBSD())
// #bool true  (on BSD variants)
// #bool false (elsewhere)
IsContainerOS

IsContainerOS reports whether this OS is typically used as a container base.

env.Dump(env.IsContainerOS())
// #bool true  (on Linux)
// #bool false (on macOS/Windows)
IsLinux

IsLinux reports whether the runtime OS is Linux.

env.Dump(env.IsLinux())
// #bool true  (on Linux)
// #bool false (on other OSes)
IsMac

IsMac reports whether the runtime OS is macOS (Darwin).

env.Dump(env.IsMac())
// #bool true  (on macOS)
// #bool false (elsewhere)
IsUnix

IsUnix reports whether the OS is Unix-like.

env.Dump(env.IsUnix())
// #bool true  (on Unix-like OSes)
// #bool false (e.g., on Windows or Plan 9)
IsWindows

IsWindows reports whether the runtime OS is Windows.

env.Dump(env.IsWindows())
// #bool true  (on Windows)
// #bool false (elsewhere)
OS

OS returns the current operating system identifier.

Example: inspect GOOS

env.Dump(env.OS())
// #string "linux"   (on Linux)
// #string "darwin"  (on macOS)
// #string "windows" (on Windows)

Typed getters

Child

Child returns a new scope rooted at the current prefix plus name.

Example: named child scope

_ = os.Setenv("STORAGE_PUBLIC_ROOT", "storage/app/public")

public := env.WithPrefix("STORAGE").Child("PUBLIC")
env.Dump(
	public.Key("ROOT"),
	public.Get("ROOT", "storage/app/public"),
)
// #string "STORAGE_PUBLIC_ROOT"
// #string "storage/app/public"
ChildNames

ChildNames discovers named child scopes under the current prefix.

Example: discover child names

_ = os.Setenv("STORAGE_DRIVER", "local")
_ = os.Setenv("STORAGE_ROOT", "storage/app/private")
_ = os.Setenv("STORAGE_PUBLIC_ROOT", "storage/app/public")
_ = os.Setenv("STORAGE_AVATARS_BUCKET", "my-bucket")
_ = os.Setenv("STORAGE_AVATARS_REGION", "us-east-1")

names := env.WithPrefix("STORAGE").ChildNames([]string{
	"DRIVER",
	"ROOT",
	"BUCKET",
	"REGION",
})
env.Dump(names)
// #[]string [
//  0 => "AVATARS" #string
//  1 => "PUBLIC" #string
// ]
Get

Get returns the environment variable for key or fallback when empty.

Example: fallback when unset

os.Unsetenv("DB_HOST")
host := env.Get("DB_HOST", "localhost")
env.Dump(host)
// #string "localhost"

Example: prefer existing value

_ = os.Setenv("DB_HOST", "db.internal")
host = env.Get("DB_HOST", "localhost")
env.Dump(host)
// #string "db.internal"
GetBool

GetBool parses a boolean from an environment variable or fallback string.

Example: numeric truthy

_ = os.Setenv("DEBUG", "1")
debug := env.GetBool("DEBUG", "false")
env.Dump(debug)
// #bool true

Example: fallback string

os.Unsetenv("DEBUG")
debug = env.GetBool("DEBUG", "false")
env.Dump(debug)
// #bool false
GetDuration

GetDuration parses a Go duration string (e.g. "5s", "10m", "1h").

Example: override request timeout

_ = os.Setenv("HTTP_TIMEOUT", "30s")
timeout := env.GetDuration("HTTP_TIMEOUT", "5s")
env.Dump(timeout)
// #time.Duration 30s

Example: fallback when unset

os.Unsetenv("HTTP_TIMEOUT")
timeout = env.GetDuration("HTTP_TIMEOUT", "5s")
env.Dump(timeout)
// #time.Duration 5s
GetEnum

GetEnum ensures the environment variable's value is in the allowed list.

Example: accept only staged environments

_ = os.Setenv("APP_ENV", "production")
appEnv := env.GetEnum("APP_ENV", "local", []string{"local", "staging", "production"})
env.Dump(appEnv)
// #string "production"

Example: fallback when unset

os.Unsetenv("APP_ENV")
appEnv = env.GetEnum("APP_ENV", "local", []string{"local", "staging", "production"})
env.Dump(appEnv)
// #string "local"
GetFloat

GetFloat parses a float64 from an environment variable or fallback string.

Example: override threshold

_ = os.Setenv("THRESHOLD", "0.82")
threshold := env.GetFloat("THRESHOLD", "0.75")
env.Dump(threshold)
// #float64 0.82

Example: fallback with decimal string

os.Unsetenv("THRESHOLD")
threshold = env.GetFloat("THRESHOLD", "0.75")
env.Dump(threshold)
// #float64 0.75
GetInt

GetInt parses an int from an environment variable or fallback string.

Example: fallback used

os.Unsetenv("PORT")
port := env.GetInt("PORT", "3000")
env.Dump(port)
// #int 3000

Example: env overrides fallback

_ = os.Setenv("PORT", "8080")
port = env.GetInt("PORT", "3000")
env.Dump(port)
// #int 8080
GetInt64

GetInt64 parses an int64 from an environment variable or fallback string.

Example: parse large numbers safely

_ = os.Setenv("MAX_SIZE", "1048576")
size := env.GetInt64("MAX_SIZE", "512")
env.Dump(size)
// #int64 1048576

Example: fallback when unset

os.Unsetenv("MAX_SIZE")
size = env.GetInt64("MAX_SIZE", "512")
env.Dump(size)
// #int64 512
GetMap

GetMap parses key=value pairs separated by commas into a map.

Example: parse throttling config

_ = os.Setenv("LIMITS", "read=10, write=5, burst=20")
limits := env.GetMap("LIMITS", "")
env.Dump(limits)
// #map[string]string [
//  "burst" => "20" #string
//  "read"  => "10" #string
//  "write" => "5" #string
// ]

Example: returns empty map when unset or blank

os.Unsetenv("LIMITS")
limits = env.GetMap("LIMITS", "")
env.Dump(limits)
// #map[string]string []
GetMapInt

GetMapInt parses key=int pairs separated by commas into a map. Invalid, missing, or non-positive values fall back to defaultValue.

Example: parse worker queue weights

_ = os.Setenv("QUEUE_WEIGHTS", "critical=6, default=3, low=1")
weights := env.GetMapInt("QUEUE_WEIGHTS", "", 1)
env.Dump(weights)
// #map[string]int [
//  "critical" => 6 #int
//  "default"  => 3 #int
//  "low"      => 1 #int
// ]

Example: invalid values use defaultValue

os.Unsetenv("QUEUE_WEIGHTS")
weights = env.GetMapInt("QUEUE_WEIGHTS", "critical=,default=0,low=nope,misc", 2)
env.Dump(weights)
// #map[string]int [
//  "critical" => 2 #int
//  "default"  => 2 #int
//  "low"      => 2 #int
//  "misc"     => 2 #int
// ]
GetSlice

GetSlice splits a comma-separated string into a []string with trimming.

Example: trimmed addresses

_ = os.Setenv("PEERS", "10.0.0.1, 10.0.0.2")
peers := env.GetSlice("PEERS", "")
env.Dump(peers)
// #[]string [
//  0 => "10.0.0.1" #string
//  1 => "10.0.0.2" #string
// ]

Example: empty becomes empty slice

os.Unsetenv("PEERS")
peers = env.GetSlice("PEERS", "")
env.Dump(peers)
// #[]string []
GetUint

GetUint parses a uint from an environment variable or fallback string.

Example: defaults to fallback when missing

os.Unsetenv("WORKERS")
workers := env.GetUint("WORKERS", "4")
env.Dump(workers)
// #uint 4

Example: uses provided unsigned value

_ = os.Setenv("WORKERS", "16")
workers = env.GetUint("WORKERS", "4")
env.Dump(workers)
// #uint 16
GetUint64

GetUint64 parses a uint64 from an environment variable or fallback string.

Example: high range values

_ = os.Setenv("MAX_ITEMS", "5000")
maxItems := env.GetUint64("MAX_ITEMS", "100")
env.Dump(maxItems)
// #uint64 5000

Example: fallback when unset

os.Unsetenv("MAX_ITEMS")
maxItems = env.GetUint64("MAX_ITEMS", "100")
env.Dump(maxItems)
// #uint64 100
MustGet

MustGet returns the value of key or panics if missing/empty.

Example: required secret

_ = os.Setenv("API_SECRET", "s3cr3t")
secret := env.MustGet("API_SECRET")
env.Dump(secret)
// #string "s3cr3t"

Example: panic on missing value

os.Unsetenv("API_SECRET")
secret = env.MustGet("API_SECRET") // panics: env variable missing: API_SECRET
MustGetBool

MustGetBool panics if missing or invalid.

Example: gate features explicitly

_ = os.Setenv("FEATURE_ENABLED", "true")
enabled := env.MustGetBool("FEATURE_ENABLED")
env.Dump(enabled)
// #bool true

Example: panic on invalid value

_ = os.Setenv("FEATURE_ENABLED", "maybe")
_ = env.MustGetBool("FEATURE_ENABLED") // panics when parsing
MustGetInt

MustGetInt panics if the value is missing or not an int.

Example: ensure numeric port

_ = os.Setenv("PORT", "8080")
port := env.MustGetInt("PORT")
env.Dump(port)
// #int 8080

Example: panic on bad value

_ = os.Setenv("PORT", "not-a-number")
_ = env.MustGetInt("PORT") // panics when parsing
WithPrefix

WithPrefix returns a scope rooted at prefix after minimal normalization.

Example: root scope access

_ = os.Setenv("STORAGE_DRIVER", "local")
_ = os.Setenv("STORAGE_ROOT", "storage/app/private")

storage := env.WithPrefix(" STORAGE ")
env.Dump(
	storage.Key("DRIVER"),
	storage.Get("DRIVER", "s3"),
	storage.Get("ROOT", "storage/app/private"),
)
// #string "STORAGE_DRIVER"
// #string "local"
// #string "storage/app/private"

License

MIT

Documentation

Index

Constants

View Source
const (
	Testing    = "testing"
	Local      = "local"
	Staging    = "staging"
	Production = "production"
)

environment helpers

View Source
const MaxDirectorySeekLevels int = 10

MaxDirectorySeekLevels is the number of directory levels a .env file needs to be searched in

Variables

This section is empty.

Functions

func Arch

func Arch() string

Arch returns the CPU architecture the binary is running on. @group Runtime @behavior readonly

Mirrors runtime.GOARCH; tests may override via the internal shim.

Example: print GOARCH

env.Dump(env.Arch())
// #string "amd64"
// #string "arm64"

func Dump

func Dump(vs ...any)

Dump is a convenience function that calls godump.Dump. @group Debugging @behavior readonly

Example: integers

nums := []int{1, 2, 3}
env.Dump(nums)
// #[]int [
//   0 => 1 #int
//   1 => 2 #int
//   2 => 3 #int
// ]

Example: multiple values

env.Dump("status", map[string]int{"ok": 1, "fail": 0})
// #string "status"
// #map[string]int [
//   "fail" => 0 #int
//   "ok"   => 1 #int
// ]

func Get

func Get(key, fallback string) string

Get returns the environment variable for key or fallback when empty. @group Typed getters @behavior readonly

Examples use github.com/goforj/godump to illustrate the concrete type.

Example: fallback when unset

os.Unsetenv("DB_HOST")
host := env.Get("DB_HOST", "localhost")
env.Dump(host)
// #string "localhost"

Example: prefer existing value

_ = os.Setenv("DB_HOST", "db.internal")
host = env.Get("DB_HOST", "localhost")
env.Dump(host)
// #string "db.internal"

func GetAppEnv

func GetAppEnv() string

GetAppEnv returns the current APP_ENV (empty string if unset). @group Application environment @behavior readonly

Example: simple retrieval

_ = os.Setenv("APP_ENV", "staging")
env.Dump(env.GetAppEnv())
// #string "staging"

func GetBool

func GetBool(key, fallback string) bool

GetBool parses a boolean from an environment variable or fallback string. @group Typed getters @behavior readonly

Accepted values: true/false, 1/0, t/f (case-insensitive). Invalid entries fall back.

Example: numeric truthy

_ = os.Setenv("DEBUG", "1")
debug := env.GetBool("DEBUG", "false")
env.Dump(debug)
// #bool true

Example: fallback string

os.Unsetenv("DEBUG")
debug = env.GetBool("DEBUG", "false")
env.Dump(debug)
// #bool false

func GetDuration

func GetDuration(key, fallback string) time.Duration

GetDuration parses a Go duration string (e.g. "5s", "10m", "1h"). @group Typed getters @behavior readonly

Example: override request timeout

_ = os.Setenv("HTTP_TIMEOUT", "30s")
timeout := env.GetDuration("HTTP_TIMEOUT", "5s")
env.Dump(timeout)
// #time.Duration 30s

Example: fallback when unset

os.Unsetenv("HTTP_TIMEOUT")
timeout = env.GetDuration("HTTP_TIMEOUT", "5s")
env.Dump(timeout)
// #time.Duration 5s

func GetEnum

func GetEnum(key, fallback string, allowed []string) string

GetEnum ensures the environment variable's value is in the allowed list. @group Typed getters @behavior readonly

Returns fallback when the environment value is not in the allowed slice.

Example: accept only staged environments

_ = os.Setenv("APP_ENV", "production")
appEnv := env.GetEnum("APP_ENV", "local", []string{"local", "staging", "production"})
env.Dump(appEnv)
// #string "production"

Example: fallback when unset

os.Unsetenv("APP_ENV")
appEnv = env.GetEnum("APP_ENV", "local", []string{"local", "staging", "production"})
env.Dump(appEnv)
// #string "local"

func GetFloat

func GetFloat(key, fallback string) float64

GetFloat parses a float64 from an environment variable or fallback string. @group Typed getters @behavior readonly

Example: override threshold

_ = os.Setenv("THRESHOLD", "0.82")
threshold := env.GetFloat("THRESHOLD", "0.75")
env.Dump(threshold)
// #float64 0.82

Example: fallback with decimal string

os.Unsetenv("THRESHOLD")
threshold = env.GetFloat("THRESHOLD", "0.75")
env.Dump(threshold)
// #float64 0.75

func GetInt

func GetInt(key, fallback string) int

GetInt parses an int from an environment variable or fallback string. @group Typed getters @behavior readonly

Example: fallback used

os.Unsetenv("PORT")
port := env.GetInt("PORT", "3000")
env.Dump(port)
// #int 3000

Example: env overrides fallback

_ = os.Setenv("PORT", "8080")
port = env.GetInt("PORT", "3000")
env.Dump(port)
// #int 8080

func GetInt64

func GetInt64(key, fallback string) int64

GetInt64 parses an int64 from an environment variable or fallback string. @group Typed getters @behavior readonly

Example: parse large numbers safely

_ = os.Setenv("MAX_SIZE", "1048576")
size := env.GetInt64("MAX_SIZE", "512")
env.Dump(size)
// #int64 1048576

Example: fallback when unset

os.Unsetenv("MAX_SIZE")
size = env.GetInt64("MAX_SIZE", "512")
env.Dump(size)
// #int64 512

func GetMap

func GetMap(key, fallback string) map[string]string

GetMap parses key=value pairs separated by commas into a map. @group Typed getters @behavior readonly

Example: parse throttling config

_ = os.Setenv("LIMITS", "read=10, write=5, burst=20")
limits := env.GetMap("LIMITS", "")
env.Dump(limits)
// #map[string]string [
//  "burst" => "20" #string
//  "read"  => "10" #string
//  "write" => "5" #string
// ]

Example: returns empty map when unset or blank

os.Unsetenv("LIMITS")
limits = env.GetMap("LIMITS", "")
env.Dump(limits)
// #map[string]string []

func GetMapInt added in v2.1.0

func GetMapInt(key, fallback string, defaultValue int) map[string]int

GetMapInt parses key=int pairs separated by commas into a map. Invalid, missing, or non-positive values fall back to defaultValue. @group Typed getters @behavior readonly

Example: parse worker queue weights

_ = os.Setenv("QUEUE_WEIGHTS", "critical=6, default=3, low=1")
weights := env.GetMapInt("QUEUE_WEIGHTS", "", 1)
env.Dump(weights)
// #map[string]int [
//  "critical" => 6 #int
//  "default"  => 3 #int
//  "low"      => 1 #int
// ]

Example: invalid values use defaultValue

os.Unsetenv("QUEUE_WEIGHTS")
weights = env.GetMapInt("QUEUE_WEIGHTS", "critical=,default=0,low=nope,misc", 2)
env.Dump(weights)
// #map[string]int [
//  "critical" => 2 #int
//  "default"  => 2 #int
//  "low"      => 2 #int
//  "misc"     => 2 #int
// ]

func GetSlice

func GetSlice(key, fallback string) []string

GetSlice splits a comma-separated string into a []string with trimming. @group Typed getters @behavior readonly

Example: trimmed addresses

_ = os.Setenv("PEERS", "10.0.0.1, 10.0.0.2")
peers := env.GetSlice("PEERS", "")
env.Dump(peers)
// #[]string [
//  0 => "10.0.0.1" #string
//  1 => "10.0.0.2" #string
// ]

Example: empty becomes empty slice

os.Unsetenv("PEERS")
peers = env.GetSlice("PEERS", "")
env.Dump(peers)
// #[]string []

func GetUint

func GetUint(key, fallback string) uint

GetUint parses a uint from an environment variable or fallback string. @group Typed getters @behavior readonly

Example: defaults to fallback when missing

os.Unsetenv("WORKERS")
workers := env.GetUint("WORKERS", "4")
env.Dump(workers)
// #uint 4

Example: uses provided unsigned value

_ = os.Setenv("WORKERS", "16")
workers = env.GetUint("WORKERS", "4")
env.Dump(workers)
// #uint 16

func GetUint64

func GetUint64(key, fallback string) uint64

GetUint64 parses a uint64 from an environment variable or fallback string. @group Typed getters @behavior readonly

Example: high range values

_ = os.Setenv("MAX_ITEMS", "5000")
maxItems := env.GetUint64("MAX_ITEMS", "100")
env.Dump(maxItems)
// #uint64 5000

Example: fallback when unset

os.Unsetenv("MAX_ITEMS")
maxItems = env.GetUint64("MAX_ITEMS", "100")
env.Dump(maxItems)
// #uint64 100

func IsAppEnv

func IsAppEnv(envs ...string) bool

IsAppEnv checks if APP_ENV matches any of the provided environments. @group Application environment @behavior readonly

Example: match any allowed environment

_ = os.Setenv("APP_ENV", "staging")
env.Dump(env.IsAppEnv(env.Production, env.Staging))
// #bool true

Example: unmatched environment

_ = os.Setenv("APP_ENV", "local")
env.Dump(env.IsAppEnv(env.Production, env.Staging))
// #bool false

func IsAppEnvLocal

func IsAppEnvLocal() bool

IsAppEnvLocal checks if APP_ENV is "local". @group Application environment @behavior readonly

Example:

_ = os.Setenv("APP_ENV", env.Local)
env.Dump(env.IsAppEnvLocal())
// #bool true

func IsAppEnvLocalOrStaging

func IsAppEnvLocalOrStaging() bool

IsAppEnvLocalOrStaging checks if APP_ENV is either "local" or "staging". @group Application environment @behavior readonly

Example:

_ = os.Setenv("APP_ENV", env.Local)
env.Dump(env.IsAppEnvLocalOrStaging())
// #bool true

func IsAppEnvProduction

func IsAppEnvProduction() bool

IsAppEnvProduction checks if APP_ENV is "production". @group Application environment @behavior readonly

Example:

_ = os.Setenv("APP_ENV", env.Production)
env.Dump(env.IsAppEnvProduction())
// #bool true

func IsAppEnvStaging

func IsAppEnvStaging() bool

IsAppEnvStaging checks if APP_ENV is "staging". @group Application environment @behavior readonly

Example:

_ = os.Setenv("APP_ENV", env.Staging)
env.Dump(env.IsAppEnvStaging())
// #bool true

func IsAppEnvTesting

func IsAppEnvTesting() bool

IsAppEnvTesting reports whether APP_ENV is "testing" or the process looks like `go test`. @group Application environment @behavior readonly

Checks APP_ENV, the -test.v flag, and arguments ending with ".test" or "-test.run".

Example: APP_ENV explicitly testing

_ = os.Setenv("APP_ENV", env.Testing)
env.Dump(env.IsAppEnvTesting())
// #bool true

Example: no test markers

_ = os.Unsetenv("APP_ENV")
env.Dump(env.IsAppEnvTesting())
// #bool false (outside of test binaries)

func IsAppEnvTestingOrLocal

func IsAppEnvTestingOrLocal() bool

IsAppEnvTestingOrLocal checks if APP_ENV is "testing" or "local". @group Application environment @behavior readonly

Example:

_ = os.Setenv("APP_ENV", env.Testing)
env.Dump(env.IsAppEnvTestingOrLocal())
// #bool true

func IsBSD

func IsBSD() bool

IsBSD reports whether the runtime OS is any BSD variant. @group Runtime @behavior readonly

BSD identifiers include: freebsd, openbsd, netbsd, dragonfly.

Example:

env.Dump(env.IsBSD())
// #bool true  (on BSD variants)
// #bool false (elsewhere)

func IsContainer

func IsContainer() bool

IsContainer detects common container runtimes (Docker, containerd, Kubernetes, Podman). @group Container detection @behavior readonly

Example: host vs container

env.Dump(env.IsContainer())
// #bool true  (inside most containers)
// #bool false (on bare-metal/VM hosts)

func IsContainerOS

func IsContainerOS() bool

IsContainerOS reports whether this OS is *typically* used as a container base. @group Runtime @behavior readonly

This does NOT indicate you are inside a container — only that the OS is usually the base for container images (currently Linux).

Example:

env.Dump(env.IsContainerOS())
// #bool true  (on Linux)
// #bool false (on macOS/Windows)

func IsDocker

func IsDocker() bool

IsDocker reports whether the current process is running in a Docker container. @group Container detection @behavior readonly

Heuristics: presence of /.dockerenv or Docker-related cgroup markers.

Example: typical host

env.Dump(env.IsDocker())
// #bool false (unless inside Docker)

func IsDockerHost

func IsDockerHost() bool

IsDockerHost reports whether this container behaves like a Docker host. @group Container detection @behavior readonly

True when docker.sock is available but container-level cgroups are absent.

Example:

env.Dump(env.IsDockerHost())
// #bool true  (when acting as Docker host)
// #bool false (for normal containers/hosts)

func IsDockerInDocker

func IsDockerInDocker() bool

IsDockerInDocker reports whether we are inside a Docker-in-Docker environment. @group Container detection @behavior readonly

Requires /.dockerenv to be present and a docker.sock exposed to the container.

Example:

env.Dump(env.IsDockerInDocker())
// #bool true  (inside DinD containers)
// #bool false (on hosts or non-DinD containers)

func IsEnvLoaded

func IsEnvLoaded() bool

IsEnvLoaded reports whether Load or LoadEnvFileIfExists was executed in this process. @group Environment loading @behavior readonly

Example:

env.Dump(env.IsEnvLoaded())
// #bool true  (after Load)
// #bool false (otherwise)

func IsHostEnvironment

func IsHostEnvironment() bool

IsHostEnvironment reports whether the process is running *outside* any container or orchestrated runtime. @group Container detection @behavior readonly

Being a Docker host does NOT count as being in a container.

Example:

env.Dump(env.IsHostEnvironment())
// #bool true  (on bare-metal/VM hosts)
// #bool false (inside containers)

func IsKubernetes

func IsKubernetes() bool

IsKubernetes reports whether the process is running inside Kubernetes. @group Container detection @behavior readonly

Checks the KUBERNETES_SERVICE_HOST env var and kubepods cgroup markers.

Example:

env.Dump(env.IsKubernetes())
// #bool true  (inside Kubernetes pods)
// #bool false (elsewhere)

func IsLinux

func IsLinux() bool

IsLinux reports whether the runtime OS is Linux. @group Runtime @behavior readonly

Example:

env.Dump(env.IsLinux())
// #bool true  (on Linux)
// #bool false (on other OSes)

func IsMac

func IsMac() bool

IsMac reports whether the runtime OS is macOS (Darwin). @group Runtime @behavior readonly

Example:

env.Dump(env.IsMac())
// #bool true  (on macOS)
// #bool false (elsewhere)

func IsUnix

func IsUnix() bool

IsUnix reports whether the OS is Unix-like. @group Runtime @behavior readonly

Returns true for Linux, macOS, BSD, Solaris, and AIX identifiers.

Example:

env.Dump(env.IsUnix())
// #bool true  (on Unix-like OSes)
// #bool false (e.g., on Windows or Plan 9)

func IsWindows

func IsWindows() bool

IsWindows reports whether the runtime OS is Windows. @group Runtime @behavior readonly

Example:

env.Dump(env.IsWindows())
// #bool true  (on Windows)
// #bool false (elsewhere)

func Load added in v2.3.0

func Load() error

Load loads .env with optional layering for .env.local/.env.staging/.env.production, plus .env.testing/.env.host when present. It only applies once per process; subsequent calls return without reloading because the result is cached. Use Reload to re-read env files after the first load. @group Environment loading @behavior mutates-process-env

Behavior:

  • Sets APP_ENV=local when unset.
  • Chooses .env.testing when APP_ENV indicates tests (or Go test flags are present).
  • Loads .env first when present; .env.<app-env> overlays for local/staging/production.
  • Loads .env.host for host-to-container networking when running on the host or DinD.
  • Idempotent: subsequent calls no-op after the first load.

Example: test-specific env file

tmp, _ := os.MkdirTemp("", "envdoc")
_ = os.WriteFile(filepath.Join(tmp, ".env.testing"), []byte("PORT=9090\nENV_DEBUG=0"), 0o644)
_ = os.Chdir(tmp)
_ = os.Setenv("APP_ENV", env.Testing)

_ = env.Load()
env.Dump(os.Getenv("PORT"))
// #string "9090"

Example: default .env on a host

_ = os.WriteFile(".env", []byte("SERVICE=api\nENV_DEBUG=3"), 0o644)
_ = env.Load()
env.Dump(os.Getenv("SERVICE"))
// #string "api"

func LoadEnvFileIfExists

func LoadEnvFileIfExists() error

LoadEnvFileIfExists is a compatibility alias for Load. @group Environment loading

Example:

_ = env.LoadEnvFileIfExists()

func MustGet

func MustGet(key string) string

MustGet returns the value of key or panics if missing/empty. @group Typed getters @behavior panic

Example: required secret

_ = os.Setenv("API_SECRET", "s3cr3t")
secret := env.MustGet("API_SECRET")
env.Dump(secret)
// #string "s3cr3t"

Example: panic on missing value

os.Unsetenv("API_SECRET")
secret = env.MustGet("API_SECRET") // panics: env variable missing: API_SECRET

func MustGetBool

func MustGetBool(key string) bool

MustGetBool panics if missing or invalid. @group Typed getters @behavior panic

Example: gate features explicitly

_ = os.Setenv("FEATURE_ENABLED", "true")
enabled := env.MustGetBool("FEATURE_ENABLED")
env.Dump(enabled)
// #bool true

Example: panic on invalid value

_ = os.Setenv("FEATURE_ENABLED", "maybe")
_ = env.MustGetBool("FEATURE_ENABLED") // panics when parsing

func MustGetInt

func MustGetInt(key string) int

MustGetInt panics if the value is missing or not an int. @group Typed getters @behavior panic

Example: ensure numeric port

_ = os.Setenv("PORT", "8080")
port := env.MustGetInt("PORT")
env.Dump(port)
// #int 8080

Example: panic on bad value

_ = os.Setenv("PORT", "not-a-number")
_ = env.MustGetInt("PORT") // panics when parsing

func OS

func OS() string

OS returns the current operating system identifier. @group Runtime @behavior readonly

Mirrors runtime.GOOS; tests may override via the internal shim.

Example: inspect GOOS

env.Dump(env.OS())
// #string "linux"   (on Linux)
// #string "darwin"  (on macOS)
// #string "windows" (on Windows)

func Reload added in v2.4.0

func Reload() error

Reload re-applies the same layered env loading as Load, even if Load already ran earlier in the same process. @group Environment loading @behavior mutates-process-env

Behavior:

  • Sets APP_ENV=local when unset.
  • Re-runs the same .env/.env.<app-env>/.env.host/.env.testing layering.
  • Uses overload semantics, so reloaded values replace previously loaded ones.

Example: refresh changed env files

_ = os.WriteFile(".env", []byte("SERVICE=api"), 0o644)
_ = env.Load()
_ = os.WriteFile(".env", []byte("SERVICE=worker"), 0o644)
_ = env.Reload()
env.Dump(os.Getenv("SERVICE"))
// #string "worker"

func SetAppEnv

func SetAppEnv(appEnv string) error

SetAppEnv sets APP_ENV to a supported value. @group Application environment @behavior mutates-process-env

Returns an error when the environment is unsupported.

Example: set a supported environment

_ = env.SetAppEnv(env.Staging)
env.Dump(env.GetAppEnv())
// #string "staging"

func SetAppEnvLocal

func SetAppEnvLocal() error

SetAppEnvLocal sets APP_ENV to "local". @group Application environment @behavior mutates-process-env

Example:

_ = env.SetAppEnvLocal()
env.Dump(env.GetAppEnv())
// #string "local"

func SetAppEnvProduction

func SetAppEnvProduction() error

SetAppEnvProduction sets APP_ENV to "production". @group Application environment @behavior mutates-process-env

Example:

_ = env.SetAppEnvProduction()
env.Dump(env.GetAppEnv())
// #string "production"

func SetAppEnvStaging

func SetAppEnvStaging() error

SetAppEnvStaging sets APP_ENV to "staging". @group Application environment @behavior mutates-process-env

Example:

_ = env.SetAppEnvStaging()
env.Dump(env.GetAppEnv())
// #string "staging"

func SetAppEnvTesting

func SetAppEnvTesting() error

SetAppEnvTesting sets APP_ENV to "testing". @group Application environment @behavior mutates-process-env

Example:

_ = env.SetAppEnvTesting()
env.Dump(env.GetAppEnv())
// #string "testing"

Types

type Scope added in v2.2.0

type Scope struct {
	// contains filtered or unexported fields
}

Scope composes a stable environment variable prefix for related keys.

func WithPrefix added in v2.2.0

func WithPrefix(prefix string) Scope

WithPrefix returns a scope rooted at prefix after minimal normalization. @group Typed getters @behavior readonly

Example: root scope access

_ = os.Setenv("STORAGE_DRIVER", "local")
_ = os.Setenv("STORAGE_ROOT", "storage/app/private")

storage := env.WithPrefix(" STORAGE ")
env.Dump(
	storage.Key("DRIVER"),
	storage.Get("DRIVER", "s3"),
	storage.Get("ROOT", "storage/app/private"),
)
// #string "STORAGE_DRIVER"
// #string "local"
// #string "storage/app/private"

func (Scope) Child added in v2.2.0

func (s Scope) Child(name string) Scope

Child returns a new scope rooted at the current prefix plus name. @group Typed getters @behavior readonly

Example: named child scope

_ = os.Setenv("STORAGE_PUBLIC_ROOT", "storage/app/public")

public := env.WithPrefix("STORAGE").Child("PUBLIC")
env.Dump(
	public.Key("ROOT"),
	public.Get("ROOT", "storage/app/public"),
)
// #string "STORAGE_PUBLIC_ROOT"
// #string "storage/app/public"

func (Scope) ChildNames added in v2.2.0

func (s Scope) ChildNames(rootKeys []string) []string

ChildNames discovers named child scopes under the current prefix. @group Typed getters @behavior readonly

Example: discover child names

_ = os.Setenv("STORAGE_DRIVER", "local")
_ = os.Setenv("STORAGE_ROOT", "storage/app/private")
_ = os.Setenv("STORAGE_PUBLIC_ROOT", "storage/app/public")
_ = os.Setenv("STORAGE_AVATARS_BUCKET", "my-bucket")
_ = os.Setenv("STORAGE_AVATARS_REGION", "us-east-1")

names := env.WithPrefix("STORAGE").ChildNames([]string{
	"DRIVER",
	"ROOT",
	"BUCKET",
	"REGION",
})
env.Dump(names)
// #[]string [
//  0 => "AVATARS" #string
//  1 => "PUBLIC" #string
// ]

func (Scope) Get added in v2.2.0

func (s Scope) Get(key, fallback string) string

Get returns the string value for key within the scope.

func (Scope) GetBool added in v2.2.0

func (s Scope) GetBool(key, fallback string) bool

GetBool returns the bool value for key within the scope.

func (Scope) GetDuration added in v2.2.0

func (s Scope) GetDuration(key, fallback string) time.Duration

GetDuration returns the duration value for key within the scope.

func (Scope) GetEnum added in v2.2.0

func (s Scope) GetEnum(key, fallback string, allowed []string) string

GetEnum returns the enum value for key within the scope.

func (Scope) GetFloat added in v2.2.0

func (s Scope) GetFloat(key, fallback string) float64

GetFloat returns the float64 value for key within the scope.

func (Scope) GetInt added in v2.2.0

func (s Scope) GetInt(key, fallback string) int

GetInt returns the int value for key within the scope.

func (Scope) GetInt64 added in v2.2.0

func (s Scope) GetInt64(key, fallback string) int64

GetInt64 returns the int64 value for key within the scope.

func (Scope) GetMap added in v2.2.0

func (s Scope) GetMap(key, fallback string) map[string]string

GetMap returns the string map value for key within the scope.

func (Scope) GetMapInt added in v2.2.0

func (s Scope) GetMapInt(key, fallback string, defaultValue int) map[string]int

GetMapInt returns the int map value for key within the scope.

func (Scope) GetSlice added in v2.2.0

func (s Scope) GetSlice(key, fallback string) []string

GetSlice returns the string slice value for key within the scope.

func (Scope) GetUint added in v2.2.0

func (s Scope) GetUint(key, fallback string) uint

GetUint returns the uint value for key within the scope.

func (Scope) GetUint64 added in v2.2.0

func (s Scope) GetUint64(key, fallback string) uint64

GetUint64 returns the uint64 value for key within the scope.

func (Scope) Key added in v2.2.0

func (s Scope) Key(key string) string

Key builds the fully qualified environment key for key within the scope.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL