Skip to content

/flags/nodejs/node-env-file

node --env-file=.env: load environment variables without dotenv

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated
tool
Node.js
command
node
flag
--env-file=FILE
default
none (no file is loaded)
since
20.6.0

node --env-file=.env app.js reads KEY=value lines from .env and adds them to process.env before your code runs. It replaces the dotenv package for the common case. Variables that are already set in the real environment win over the file. The flag exists since Node.js 20.6; a missing file is an error, and --env-file-if-exists (Node.js 22.9+) skips it silently.

Example

bash
cat > .env <<'EOF'
# comments and blank lines are ignored
PORT=8080
GREETING="hello world"
DB_URL=postgres://localhost/app
EOF
cat > app.js <<'EOF'
console.log(process.env.PORT, process.env.GREETING, process.env.DB_URL);
EOF
echo "--- without the flag"
node app.js
echo "--- with --env-file"
node --env-file=.env app.js
echo "--- environment wins over the file"
PORT=9000 node --env-file=.env app.js
echo "--- missing file"
node --env-file=missing.env app.js 2>&1 | head -1 | sed -E 's#^.*node(\.exe)?: #node: #'   # strip the platform-specific path of node

Output

--- without the flag
undefined undefined undefined
--- with --env-file
8080 hello world postgres://localhost/app
--- environment wins over the file
9000 hello world postgres://localhost/app
--- missing file
node: missing.env: not found

Rules

SituationBehaviour
Variable set in the environment and in the fileThe environment value is kept
Several --env-file flagsFiles are read in order; a later file overrides an earlier one
File does not existnode exits with an error (use --env-file-if-exists to ignore)
Quotes around valuesRemoved, as GREETING shows
Lines starting with #Comments

From code: process.loadEnvFile()

js
process.loadEnvFile();              // reads ./.env (Node.js 21.7+ / 20.12+)
process.loadEnvFile("config.env");  // or a given path

File format

Node.js defines its own .env syntax, documented with the DotEnv API:

SyntaxResult
PORT=3000PORT is the string 3000; every value is a string
NAME = valueSpaces around the key and the unquoted value are trimmed
MSG="a = b # c"Inside quotes, = and # are ordinary characters
KEY=value # noteText after # on an unquoted line is a comment
export KEY=valueThe export keyword is ignored, so the file can also be sourced by a shell
A quoted value with line breaksThe value spans several lines (Node.js 21.7+ / 20.12+)
1_VAR=xInvalid name: names use letters, digits and underscores and cannot start with a digit

Variables that configure Node.js itself, such as NODE_OPTIONS, are applied when they come from the file, so a .env can turn on other runtime flags.

References to other variables are not expanded, and nothing is converted to a number or boolean:

bash
cat > .env <<'EOF'
HOST=db.local
URL=postgres://${HOST}/app
DEBUG=false
EOF
node --env-file=.env -p 'process.env.URL + " | " + typeof process.env.DEBUG'

Output

postgres://${HOST}/app | string

Versions

--env-file was added in Node.js 20.6.0 as an experimental flag and became stable in 24.10.0 and 22.21.0; multi-line values arrived in 21.7.0 and 20.12.0. On Node.js 18 and older the flag does not exist and node refuses to start with a "bad option" error, so projects that still support those versions keep using the dotenv package. To parse a file without touching process.env, util.parseEnv(text) returns the variables as a plain object.

When dotenv is still useful

The built-in loader covers the common case. The dotenv ecosystem adds things Node.js does not do, such as variable expansion with dotenv-expand; if you rely on it, keep the packages.

FAQ

Does --env-file override variables that are already set?

No. A variable that exists in the real environment keeps its value; the file only fills in the ones that are missing. Between several files, the later file wins.

Can I use --env-file in an npm script?

Yes, it is an ordinary node flag, so a start script of node --env-file=.env server.js works. Use --env-file-if-exists when the file is optional, for example in CI where the variables come from the pipeline.

Are numbers and booleans in .env converted?

No. Every value becomes a string in process.env, so PORT=3000 is '3000' and DEBUG=false is the non-empty string 'false'. Convert them in your code.

Sources