Node.js applications often need configuration values that change between a local shell, a CI job, and a deployment target. A .env file gives a development process a repeatable set of environment variables without hard-coding those values into JavaScript source.
The built-in --env-file flag loads key-value pairs before the entry script runs, so application code reads them from process.env like any other environment variable. This startup-time path does not require the third-party dotenv package for a simple local configuration file.
Keep dotenv files trusted and local when they contain secrets. Existing shell environment values take precedence over file values, and the CLI env-file loader also parses Node startup options from NODE_OPTIONS, so a checked-in or untrusted file can change how the process starts.
$ cat > .env <<'EOF' APP_ENV=development PORT=3000 API_TOKEN="local-dev-token" EOF
Do not commit a real .env file that contains tokens, passwords, private endpoints, or account identifiers. Keep a separate .env.example with nonsecret variable names when the project needs a template.
const required = ["APP_ENV", "PORT", "API_TOKEN"]; for (const name of required) { if (!process.env[name]) { console.error(`missing ${name}`); process.exit(1); } } console.log(`environment=${process.env.APP_ENV}`); console.log(`port=${process.env.PORT}`); console.log("apiToken=loaded");
Only the presence of API_TOKEN is printed; the token value stays out of terminal output.
$ node --env-file=.env app.mjs environment=development port=3000 apiToken=loaded
The env file path is resolved from the current working directory. Use a different path after --env-file= when the file is stored elsewhere.
$ PORT=4000 node --env-file=.env app.mjs environment=development port=4000 apiToken=loaded
An existing environment variable wins over the same key in the env file. The assignment syntax shown is for POSIX shells; use the equivalent syntax for the shell that starts the process.
$ node --env-file=.env --env-file-if-exists=.env.local app.mjs .env.local not found. Continuing without it. environment=development port=3000 apiToken=loaded
Place an optional local override after the base file when values in .env.local should replace matching values from .env whenever that file is present.
$ rm .env app.mjs