Node.js Environment Variables
Node.js environment variables store configuration such as port numbers, database URLs and API keys outside your code. The same code can then run in development, testing and production with different settings, and secrets never end up in your Git repository.
Reading process.env
Every value in process.env is a string or undefined. Convert numbers and booleans yourself. On Windows PowerShell set a variable with $env:PORT="8080" before running node.
const port = process.env.PORT ?? 3000;
const mode = process.env.NODE_ENV ?? 'development';
console.log(`Starting in ${mode} mode on port ${port}`);$ PORT=8080 NODE_ENV=production node app.js Starting in production mode on port 8080
Using a .env File
Typing variables every time is tedious. Put them in a .env file and let Node 20.6+ load it with --env-file. On older versions, the dotenv package does the same.
# .env
PORT=4000
DATABASE_URL=postgres://user:pass@localhost:5432/shop
JWT_SECRET=change-me
# package.json
"scripts": { "dev": "node --env-file=.env --watch server.js" }$ npm run dev Starting in development mode on port 4000
Keep Secrets Out of Git
- Add .env to .gitignore before your first commit.
- Commit a .env.example with the variable names and dummy values.
- In production, set real values in your host's dashboard (Render, Railway, Vercel) or the server environment.
- If a secret is ever committed, rotate it — deleting the file does not remove it from Git history.
A Config Module with Validation
Read and check all variables in one place at startup. Failing fast with a clear message beats a mysterious crash later.
// config.js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Missing environment variable: ${name}`);
return value;
}
export const config = {
port: Number(process.env.PORT ?? 3000),
isProd: process.env.NODE_ENV === 'production',
databaseUrl: required('DATABASE_URL'),
jwtSecret: required('JWT_SECRET'),
};Error: Missing environment variable: JWT_SECRET
NODE_ENV
NODE_ENV=production is a widely used convention. Express and many libraries switch to faster, less verbose behavior when they see it, such as caching views and hiding stack traces. Set it on your production server.
Frequently asked questions
How do I use a .env file in Node.js?
On Node 20.6 or newer run node --env-file=.env app.js. On older versions install dotenv and add import "dotenv/config" at the top of your entry file.
Should I commit my .env file?
No. Add it to .gitignore and commit a .env.example instead, so secrets like passwords and API keys never reach your repository.
Why is process.env.PORT a string?
Environment variables are always strings. Convert them with Number(), parseInt() or a comparison like === "true" for booleans.