.env file syntax
oneenv supports the syntax you expect from a mature .env parser:
# A comment line.
export PATH_STYLE=ok # "export " prefix is allowed; inline comments too
PLAIN=value
QUOTED="double quoted" # escapes: \n \r \t \" \\
RAW='single quoted' # no escapes, no expansion — taken literally
MULTILINE="line one
line two" # newlines allowed inside double quotes
GREETING="Hello ${USER}" # ${VAR} / $VAR expansion — only with WithExpand()
LITERAL='$NOT_EXPANDED' # single quotes never expand
- Comments — a
#starting a line, or preceded by whitespace on a value line. exportprefix — accepted and ignored, so you cansourcethe same file.- Quotes — double quotes honour escapes and can span multiple lines; single quotes are literal.
- Expansion —
${VAR}and$VARare expanded (whenWithExpand()is set) against values already parsed in the file, falling back to the process environment. Write$$for a literal$.
Passwords and expansion. Expansion applies to the value text, so a password containing
$is rewritten:pa$$wordbecomespa$word,pa$wordbecomespa, and$ecret123becomes the empty string. Keep secrets out of expansion in one of these ways:
- declare the field as
oneenv.Secret[T], or tag it,secret/,noexpand— those are never expanded;- single-quote the value in the file:
DB_PASSWORD='pa$$word';- use
WithExpandStrict(), which turns an undefined reference into anErrUnknownVariableparse error instead of a silently blanked value.
Syntax errors come back as a *ParseError carrying the file name and
line number.
Environment-aware file cascade
WithEnvFiles() layers files by the active environment, the convention used by
Rails, Next.js and dotenv-cli. On top of each base file it also reads
<base>.local, <base>.<env> and <base>.<env>.local, each optional, later
files overriding earlier keys:
cfg, err := oneenv.Parse[Config](oneenv.WithEnvFiles())
// with APP_ENV=production, reads in increasing priority:
// .env → .env.local → .env.production → .env.production.local
The environment name comes from APP_ENV, then GO_ENV; change the sources
with WithEnvVar("MY_ENV"). FilesFor(opts...) returns the resolved list.