Environment variables and .env
An environment variable is a named value the operating system passes to a program when it starts. They hold settings that differ between your computer and the server: the port, the database address, secret keys. This way the same program can run in different places without changing its code.
process.env
All environment variables live in the process.env object. Its values are always strings:
const port = Number(process.env.PORT ?? 3000);
console.log(`Port: ${port}`);If PORT is not set, "Port: 3000" is printed. The number is obtained with Number(), the default with ??.
Setting a variable at launch
In bash (Linux, macOS) the variable is written before the command:
PORT=8080 node app.jsIn PowerShell — as a separate statement:
$env:PORT = "8080"; node app.jsIn both cases the program prints "Port: 8080".
The .env file
Typing variables every time is tedious, so they are written into a .env file in the project root — next to package.json:
PORT=8080
BLOG_TITLE=Notes by Anna
ADMIN_PASSWORD=change-meNode.js loads it when you pass the --env-file flag:
node --env-file=.env app.jsIt is convenient to add the flag to the dev script in package.json right away: "dev": "node --watch --env-file=.env src/server.js".
Loading from code
The file can also be loaded from the program itself with process.loadEnvFile():
import { writeFile } from 'node:fs/promises';
await writeFile('.env', "BLOG_TITLE=Notes by Anna\nPOSTS_PER_PAGE=5\n");
process.loadEnvFile('.env');
console.log(process.env.BLOG_TITLE); // Notes by Anna
console.log(Number(process.env.POSTS_PER_PAGE)); // 5The example first creates .env, then reads it. In a real project you write the file yourself, and only process.loadEnvFile() stays in the code.
NODE_ENV
Many libraries look at the NODE_ENV variable. On the server it is set to production, and libraries switch off debugging checks:
const isProduction = process.env.NODE_ENV === 'production';
console.log(isProduction ? 'Production mode' : 'Development mode');Common mistake
Passwords and keys must not be written in the code, and the .env file must not go into Git: otherwise everyone with access to the repository sees the secrets. Add .env to .gitignore and keep a .env.example file in the repository with the variable names but no values:
PORT=
BLOG_TITLE=
ADMIN_PASSWORD=A new team member copies it to .env and fills in their own values.