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
const port = process.env.PORT || 3000;
console.log(`Starting on port ${port}`);
node server.js PORT=4000 node server.js
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:
PORT=4000 DATABASE_URL=postgres://localhost/myapp
require("dotenv").config();
console.log("Port:", process.env.PORT);
console.log("DB:", process.env.DATABASE_URL);
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.
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.