Environment Variables & Config

Real applications need different settings in different places — a different database URL locally versus in production, a port that might already be taken. Environment variables, accessed through process.env, are the standard way to handle that without hardcoding values into the source code.

Reading an environment variable

JS server.js
const port = process.env.PORT || 3000;

console.log(`Starting on port ${port}`);
bash terminal
node server.js
PORT=4000 node server.js
Output
Starting on port 3000
Starting on port 4000

Setting PORT=4000 before the command exports it into the environment that node runs in; process.env.PORT picks it up. Without it, process.env.PORT is undefined, and || 3000 falls back to a sensible default.

Loading variables from a .env file

Typing environment variables on every command line gets old fast. Most projects instead keep them in a .env file (never committed to git) and load it with a package like dotenv:

text .env
PORT=4000
DATABASE_URL=postgres://localhost/myapp
JS server.js
require("dotenv").config();

console.log("Port:", process.env.PORT);
console.log("DB:", process.env.DATABASE_URL);
Output
Port: 4000
DB: postgres://localhost/myapp

require("dotenv").config() reads the .env file and copies its values into process.env, as if you'd set them on the command line yourself.

Note: every value on process.env is a string, always — even something that looks like a number. process.env.PORT is the string "4000", not the number 4000. Comparing it with === against a real number, or doing math on it directly, is a common source of bugs; wrap it in Number(process.env.PORT) first when you need an actual number.