Skip to content

Beginner · Node.js and Express · topic 15 of 54 · 20 min

Environment variables and config

Explanation

Environment variables are settings given to your program from outside the code, like the port number or the database address. Node.js reads them from process.env. Secrets go in a .env file that you never commit to Git, and your app should check its settings as soon as it starts.

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.

Think of it like this: Think of a hotel room locker. The hotel does not print the locker code in its brochure for everyone to read. Each guest gets the code at the front desk when they check in. Your code is the brochure; environment variables are the codes handed over at check-in.

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.

javascript
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
Runs on a server with Node.js: reading values from process.env.

.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.

bash
# .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.js
A .env file and the command that loads it.

Never 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.

output
# .gitignore
node_modules
.env

# .env.example (safe to commit)
PORT=3000
DATABASE_URL=
API_KEY=
.gitignore keeps .env out of Git; .env.example shows the names without the secrets.
SettingOn your laptop (development)On the server (production)
NODE_ENVdevelopmentproduction
PORT3000set by the hosting company
DATABASE_URLa local test databasethe real database, with a strong password
Error messagesfull details to help you debugshort 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.

Tip: Pass process.env into loadConfig(env) as an argument instead of reading process.env inside it. Then you can test it with any fake object, which is exactly what you will do in the task.
Careful: Never write a real password or API key directly in your code, not even "just for testing". Code gets copied, shared and pushed to GitHub, and bots scan GitHub for leaked keys within minutes.

Watch the lesson

Environment variables and config · 1/7

Environment variables and config

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.

javascript
import { loadConfig } from './config.js';

const config = loadConfig(process.env); // stops at once if something is missing
app.listen(config.port);
Runs on a server with Node.js: config is checked once, at startup.

Practice (0/2 done)

Task 1 · Code · Javascript

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.

Task 2 · Code · Javascript

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

Question 1

1.Where does Node.js keep environment variables?

Question 2

2.PORT=8080 is set. What is the type of process.env.PORT?

Question 3

3.Which file should you add to .gitignore?

Question 4

4.Why check the config when the app starts?

Question 5

5.How can modern Node.js load a .env file without any package?

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.

← Previous: Middleware: checks before your handler