Servers and environment
Load an environment file
Load local configuration with Node’s built-in env-file flag while keeping secrets out of source control.
8 minute lesson
A current Node release can load a dotenv-style file without another package:
node --env-file=.env server.js
The file path is resolved from the current working directory. A missing file makes the command fail, which is useful when the application requires that configuration.
Example .env:
PORT=3000
API_BASE_URL=https://api.example.com
Node adds these values to process.env. Environment values are strings, so parse and validate them before use:
const port = Number.parseInt(process.env.PORT ?? '', 10)
if (!Number.isInteger(port) || port < 1 || port > 65535) {
throw new Error('PORT must be an integer from 1 to 65535')
}
Do not let Number(undefined) silently become NaN far away from startup. Validate required configuration once, fail with the variable name, and never print secret values in an error.
An environment variable already set by the shell takes precedence over the value in the file:
PORT=4000 node --env-file=.env server.js
You can pass several --env-file flags. Later files override values from earlier files, while variables already present in the process environment still win. This supports a safe shared file plus a local override without custom merge code.
Current Node releases also provide --env-file-if-exists when an optional local file should not cause startup to fail. Use the strict flag for required production configuration so a missing file is visible.
Do not commit real secrets. Ignore .env, restrict its filesystem permissions, and provide .env.example containing variable names and harmless placeholders. Environment files reduce accidental source commits; they are not a full secret-management system.
Your action is to create a safe .env with PORT=3000, print the validated port, then override it from the shell. Try a missing and an invalid value and record each exit status without logging a secret.
Lesson completed