The config loader lets you specify environment values using JSON/YAML or JS/TS config files, then overlay them deterministically with privacy and source precedence.
Behavior: In the shipped CLI (plugin-first host) and the generator path, the loader/overlay pipeline is always active and is a no-op when no config files are present.
When enabled, the loader discovers up to three configs in the following order:
getdotenv.config.json
getdotenv.config.yaml
/ .yml
getdotenv.config.js
/ .mjs
/ .cjs
getdotenv.config.ts
/ .mts
/ .cts
getdotenv.config.json
getdotenv.config.yaml
/ .yml
getdotenv.config.js
/ .mjs
/ .cjs
getdotenv.config.ts
/ .mts
/ .cts
getdotenv.config.local.json
getdotenv.config.local.yaml
/ .yml
getdotenv.config.local.js
/ .mjs
/ .cjs
getdotenv.config.local.ts
/ .mts
/ .cts
Notes:
.local
is not expected by policy and is ignored.JSON/YAML (data only, always-on; no-op when no files are present):
dotenvToken?: string
privateToken?: string
paths?: string | string[]
loadProcess?: boolean
log?: boolean
shell?: string | boolean
scripts?: Record<string, unknown>
vars?: Record<string, string>
(global, public)envVars?: Record<string, Record<string, string>>
(per-env, public)dynamic
— use JS/TS instead.JS/TS (data + dynamic):
dynamic?: GetDotenvDynamic
— a map where values are either strings or functions of the form (vars: ProcessEnv, env?: string) => string | undefined
.TS support:
Config privacy derives from the filename suffix:
getdotenv.config.json
/ .yaml
/ .yml
(shared in VCS).getdotenv.config.local.json
/ .yaml
/ .yml
(gitignored).The loader overlays config-provided values onto the “base” file-derived dotenv values using these axes (higher wins):
dynamic
> env
> global
local
> public
project
> packaged
> base
The overlay flow:
getDotenv
(exclude dynamic; ignore programmatic vars
).dynamicPath
(lowest dynamic tier).outputPath
(write consolidated dotenv; quote multiline), log
(print final map), loadProcess
(merge into process.env
).All expansions are progressive within each slice: when applying a vars
object, keys are expanded left-to-right so later values may reference earlier results.
You can define a scripts table in config and optionally override shell behavior per script. Script strings are resolved by the cmd
and batch
commands:
{
"scripts": {
"bash-only": { "cmd": "echo $SHELL && echo OK", "shell": "/bin/bash" },
"plain": { "cmd": "node -v", "shell": false }
}
}
When a script is invoked, scripts[name].shell
(string or boolean) takes precedence over the global --shell
setting for that script.
Project files:
# getdotenv.config.yaml (public)
vars:
FOO: 'foo'
envVars:
dev:
BAR: '${FOO}-dev'
# getdotenv.config.local.yml (private)
vars:
SECRET: 's3cr3t'
JS/TS dynamic (optional):
// getdotenv.config.ts
export default {
dynamic: {
BOTH: ({ FOO = '', BAR = '' }) => `${FOO}-${BAR}`,
},
};
With --use-config-loader
(or { useConfigLoader: true }
on the host), the final map for env=dev
overlays global public (FOO
) → env public (BAR
) → global local (SECRET
) → dynamic from config (BOTH
):
{ FOO: "foo", BAR: "foo-dev", SECRET: "s3cr3t", BOTH: "foo-foo-dev" }