dotenv API reference
Read .env configuration files - the KEY=VALUE lines that keep secrets and settings out of source - with layered profiles and ${VAR} interpolation.
Single-file primitives: parse turns text into a map of string to string, read parses a file, and load parses a file and sets each variable in the process environment (via os.setEnv, unconditional override). Layered loaders: readCascade / resolve / loadCascade / autoload merge .env -> .env.local -> .env.<profile> -> .env.<profile>.local from one explicit directory, later overriding earlier, with a real OS env var always winning over a file value (a committed file cannot clobber a deployment secret). The profile comes from JENNIFER_ENV (empty = base files only).
Values handle # comments (whole-line and inline on unquoted values), blank lines, a leading export, single-quoted (fully literal) and double-quoted (expand \n / \t / \r, may span multiple physical lines) values, and ${VAR} interpolation in unquoted and double-quoted values (backward-reference only: earlier keys -> real OS env -> empty; single quotes never interpolate; no $(...) / backtick command substitution). Over fs + strings + os + path + regex + maps; pure .j, both binaries.
Import with import "dotenv.j" as dotenv;. See the dotenv guide for prose and examples.
Functions
dotenv.autoload(dir as string)
Convenience: loadCascade(dir, JENNIFER_ENV) - the layered, real-env-wins load with the profile taken from the JENNIFER_ENV environment variable (empty = base files only). The one env var this module reads to pick a profile.
Parameters
dir{string}- the base directory (usuallyos.cwd())
Returns {map of string to string} - the merged file variables
Throws
{Error}- kind "dotenv" on an invalid profile label or variable name
dotenv.load(path as string)
Read a .env file and set each variable in the process environment (via os.setEnv, unconditional override), returning the parsed map. This is the low-level primitive; for a real-env-wins layered load use loadCascade / autoload.
Parameters
path{string}- the file path
Returns {map of string to string} - the variables that were set
Throws
{Error}- on a filesystem error, or an invalid variable name
dotenv.loadCascade(dir as string, profile as string)
Merge the .env layers (readCascade) then os.setEnv each variable only when it is not already set in the real environment - a real env var is never clobbered by a committed file. A variable set to the empty string counts as unset (there is no os.hasEnv), so a file value still fills it. Returns the file map (all keys, whether or not they were set). To force-override instead, use readCascade + your own os.setEnv loop.
Parameters
dir{string}- the base directoryprofile{string}- the profile label, or "" for base files only
Returns {map of string to string} - the merged file variables
Throws
{Error}- kind "dotenv" on an invalid profile label or variable name
dotenv.parse(text as string)
Parse .env text into a map. Blank lines and # comment lines are skipped, a leading export is stripped, and each KEY=VALUE becomes an entry (later duplicates win). Double-quoted values may span multiple physical lines; ${VAR} references are interpolated (earlier keys -> real OS env -> ""). A line with no = or an empty key is ignored.
Parameters
text{string}- the.envfile contents
Returns {map of string to string} - the parsed variables
Throws
{Error}- kind "dotenv" on an unterminated multi-line double-quoted value
dotenv.read(path as string)
Read and parse a .env file, without touching the environment.
Parameters
path{string}- the file path
Returns {map of string to string} - the parsed variables
Throws
{Error}- on a filesystem error (a positionedfserror)
dotenv.readCascade(dir as string, profile as string)
Merge the .env layers from one directory into a map, without touching the environment. Reads, later overriding earlier and skipping absent files: .env -> .env.local -> .env.<profile> -> .env.<profile>.local. A ${VAR} in a later file resolves against keys from earlier files. An empty profile loads only the base files (there is no .env.default).
Parameters
dir{string}- the single base directory (no search / no walk-up)profile{string}- the profile label, or "" for base files only
Returns {map of string to string} - the merged file variables
Throws
{Error}- kind "dotenv" on an invalid profile label; an absent layer is skipped (not an error) but an unreadable one raises thefserror
dotenv.resolve(dir as string, profile as string)
The effective configuration map: readCascade overlaid by the real OS environment, so a real env var always wins over a file value. The result holds exactly the file map's keys (each taking the OS-env value when that variable is set), for a program that reads a config map instead of calling os.getEnv. Touches nothing in the environment. A variable set to the empty string in the environment counts as unset (there is no os.hasEnv), so a file value still fills it.
Parameters
dir{string}- the base directoryprofile{string}- the profile label, or "" for base files only
Returns {map of string to string} - the effective values (real env wins)