.env File Support¶
flags can load a .env file
and populate environment variables before parsing flags.
This lets you keep local configuration out of source control
and still benefit from the env tag-based option defaults.
The feature is opt-in. Default parser behaviour
is unchanged when no DotEnv-family option is set.
Quick Start¶
With DotEnv enabled, a .env file in the current working directory
is read automatically before arguments are parsed.
A missing .env is silently ignored.
.env File Format¶
# Comments start with #
HOST=localhost
PORT=5432
# Export prefix is optional
export APP_MODE=production
# Quoted values preserve whitespace
GREETING="Hello, World!"
NOTE='literal \n - no escape here'
# Inline comments (must be preceded by whitespace)
TIMEOUT=30 # seconds
Key rules:
- Keys must match
[A-Za-z0-9_.-]. - The
exportprefix is stripped. - Both
KEY=VALUEandKEY: VALUE(YAML-style) are accepted. - Single-quoted values: no variable expansion, no escape sequences.
- Double-quoted values: expansion +
\n,\r,\\escape sequences. - Unquoted values: expansion + trailing whitespace and inline comments stripped.
Variable Expansion¶
Values may reference other variables using the following syntax.
| Syntax | Behaviour |
|---|---|
$VAR |
Substitute value of VAR |
${VAR} |
Substitute value of VAR (braced form) |
${VAR:=default} |
Use VAR; if unset or empty, set it to default |
$${VAR} |
Literal ${VAR} - no substitution |
Variable lookup checks values already defined in the same .env file first,
then falls back to os.Getenv.
An undefined variable expands to an empty string.
BASE=/opt/app
DATA_DIR=${BASE}/data # -> /opt/app/data
CACHE_DIR=${TMP_DIR:=/tmp}/cache # sets TMP_DIR if unset
TEMPLATE=$${UNESCAPED} # -> literal ${UNESCAPED}
Single-quoted values are never expanded regardless of the global setting.
Parser Options¶
DotEnv- load.envbefore parsing; skip silently if missingDotEnvOverride- likeDotEnvbut overrides existing env varsDotEnvFlags- add "Env Options" group with three pre-configured flags
// Load .env, keep existing env vars intact
parser := flags.NewParser(&opts, flags.Default|flags.DotEnv)
// Load .env, overwrite existing env vars
parser := flags.NewParser(&opts, flags.Default|flags.DotEnvOverride)
// Add --env-file / --no-env / --env-override CLI flags
parser := flags.NewParser(&opts, flags.Default|flags.DotEnv|flags.DotEnvFlags)
Env Options Group (DotEnvFlags)¶
When DotEnvFlags is set, three flags are added that are pre-scanned
before the .env file is loaded:
Env Options:
--env-file=FILE Path to .env file
--no-env Disable .env file loading
--env-override Override existing environment variables from .env file
These flags are pre-scanned before the main parse,
so specifying --env-file custom.env on the command line
takes effect even for options whose defaults come from environment variables.
When ConfigFlags is also enabled,
all three flags share the unified Config Options group
alongside -c / --config FILE instead of appearing
in a standalone Env Options group.
Programmatic API¶
Use the programmatic API for full control without relying on a CLI flag.
parser := flags.NewParser(&opts, flags.Default)
// Load once manually (no override)
if err := parser.LoadDotEnv(".env", ".env.local"); err != nil {
log.Fatal(err)
}
// Load with override
if err := parser.OverloadDotEnv("production.env"); err != nil {
log.Fatal(err)
}
// Change the default file used by DotEnv option
parser.SetDotEnvFile("config/.env")
// Disable variable expansion
parser.SetDotEnvNoExpand(true)
_, err = parser.Parse()
LoadDotEnv and OverloadDotEnv accept zero or more filenames.
When called with no arguments the parser
uses file configured by SetDotEnvFile (default ".env").
A missing default file is silently ignored;
a missing explicitly named file returns an error.
Disabling Expansion¶
Call SetDotEnvNoExpand(true) to treat all $ sequences as literal characters.
This is useful when values contain dollar signs that should not be interpreted,
for example shell scripts or regular expressions.
Accessing Built-in Options¶
When DotEnvFlags is set you can retrieve the built-in options
to further customise them (rename, hide, change description, etc.):