Beginner · Node.js and Express · topic 15 of 54 · 20 min
Environment variables and config
Explanation
Settings that live outside the code
An environment variable is a named value that the operating system gives to a program when it starts, for example PORT=3000. The same code can run with different values on your laptop and on the real server, without changing a line.
In Node.js all environment variables are in the object process.env. Every value is text (a string), even numbers, and a missing one is undefined.
const port = Number(process.env.PORT) || 3000;
console.log('Starting on port', port);
console.log(process.env.NODE_ENV); // 'production' on the server, often undefined on a laptop.env files
Typing every value in the terminal is tiring, so we keep them in a file called .env in the project folder: one NAME=value per line. Modern Node.js (version 20.6 and later) can load it with the --env-file flag. Older projects use the dotenv package and add the line import "dotenv/config" at the top of server.js.
# .env (never commit this file)
PORT=4000
DATABASE_URL=postgres://localhost:5432/shop_dev
API_KEY=change-me
# start the app with it
node --env-file=.env src/server.jsNever commit .env
Git is the tool that saves the history of your code and shares it on sites like GitHub. If .env goes into Git, your passwords are in the history forever, even if you delete the file later. Add .env to a file called .gitignore so Git skips it. Instead, commit a .env.example file: the same names with fake or empty values, so teammates know what to fill in.
# .gitignore
node_modules
.env
# .env.example (safe to commit)
PORT=3000
DATABASE_URL=
API_KEY=| Setting | On your laptop (development) | On the server (production) |
|---|---|---|
| NODE_ENV | development | production |
| PORT | 3000 | set by the hosting company |
| DATABASE_URL | a local test database | the real database, with a strong password |
| Error messages | full details to help you debug | short and safe for users |
Check your config when the app starts
If DATABASE_URL is missing, it is better to stop at once with a clear message than to crash later on the first customer request with a strange error. So we write one loadConfig function that reads, checks and converts every setting at startup, and the rest of the code uses its result.
Watch the lesson
Environment variables and config · 1/7
Today: how to give your app settings and secrets without writing them in the code.
Prefer a video by a teacher? Find free videos on “node js environment variables dotenv env file tutorial” on YouTube ↗
In real life: One code base, three places
A Bengaluru startup runs the same Node.js code in three places: on each developer laptop, on a staging server for testing, and on the production server that real customers use. Only the environment variables differ: each place has its own DATABASE_URL, its own Razorpay test or live key and its own NODE_ENV. When a new developer joins, they copy .env.example to .env and fill in local values. The live payment key exists only in the production server settings, never in Git.
import { loadConfig } from './config.js';
const config = loadConfig(process.env); // stops at once if something is missing
app.listen(config.port);Practice (0/2 done)
Write getPort(env). env is an object like process.env, so values are text. Return env.PORT as a NUMBER, or 3000 when PORT is missing.
Write loadConfig(env) that returns { port, databaseUrl, nodeEnv }. Rules: PORT is optional, default 3000, but if given it must be a number, else throw new Error("PORT must be a number"). DATABASE_URL is required: if it is missing or an empty string, throw new Error("DATABASE_URL is missing"). NODE_ENV is optional, default "development".
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.