Node.js Environment Variables

Environment variables are key-value pairs stored outside of the application's source code — in the operating system or in a special configuration file — that the application can read at runtime. They are used to store sensitive or environment-specific information such as database passwords, API keys, port numbers, and secret tokens.

The core principle is simple: code that is shared (e.g., pushed to GitHub) should never contain secrets. Environment variables keep sensitive configuration separate from the codebase.

Why Are Environment Variables Important?

  • Security: Passwords, API keys, and tokens are not stored in code files that might be publicly visible.
  • Flexibility: The same code can run in different environments (development, testing, production) with different configurations — without changing the code itself.
  • Best Practice: Separating configuration from code is a widely recognized software engineering principle.

Accessing Environment Variables with process.env

Node.js makes all environment variables available through the process.env object:

// Reading an environment variable
const port = process.env.PORT;
console.log("Port:", port);

Environment variables can be set directly in the terminal before running a script:

# On macOS/Linux
PORT=5000 node app.js

# On Windows (Command Prompt)
set PORT=5000 && node app.js

The dotenv Package

Setting variables in the terminal every time is impractical. The dotenv package allows environment variables to be loaded from a .env file automatically.

Installing dotenv

npm install dotenv

Creating the .env File

Create a file named .env in the project root directory:

# .env

PORT=3000
NODE_ENV=development
DB_URI=mongodb+srv://admin:secretpassword@cluster.mongodb.net/myapp
JWT_SECRET=mySuperSecretKey_DoNotShare
API_KEY=abc123xyz789
  • Each line has the format KEY=VALUE.
  • No spaces around the equals sign.
  • Comments start with #.
  • Values do not need quotes (unless the value contains spaces).

Loading the .env File in the Application

Load dotenv at the very top of the entry file (app.js or index.js), before any other code:

// app.js
require('dotenv').config();

const express = require('express');
const app = express();

const PORT = process.env.PORT || 3000;
const DB_URI = process.env.DB_URI;
const JWT_SECRET = process.env.JWT_SECRET;

console.log("Environment:", process.env.NODE_ENV);
console.log("Server starting on port:", PORT);

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

|| 3000 provides a fallback value in case the environment variable is not defined.

Never Commit the .env File to Git

The .env file contains sensitive credentials and must never be uploaded to version control. Add it to the .gitignore file:

# .gitignore
node_modules/
.env

Sharing Configuration Without Exposing Secrets

Instead of sharing the actual .env file, a template file (.env.example) is shared with all the variable names but no real values:

# .env.example

PORT=
NODE_ENV=
DB_URI=
JWT_SECRET=
API_KEY=

Anyone who clones the project copies this file to .env and fills in their own values.

Using Environment Variables in a Full Application

// app.js
require('dotenv').config();

const express = require('express');
const mongoose = require('mongoose');

const app = express();
app.use(express.json());

// Connect to database using env variable
mongoose.connect(process.env.DB_URI)
  .then(() => console.log('Database connected'))
  .catch(err => console.log('DB error:', err.message));

// Route protected by an API key check
app.get('/api/data', function(req, res) {
  const clientKey = req.headers['x-api-key'];

  if (clientKey !== process.env.API_KEY) {
    return res.status(401).json({ error: 'Invalid API key' });
  }

  res.json({ message: 'Access granted', data: [1, 2, 3] });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Running in ${process.env.NODE_ENV} mode on port ${PORT}`));

Environment-Specific Behavior

The NODE_ENV variable is a widely used convention to identify the current environment:

if (process.env.NODE_ENV === 'development') {
  console.log('Running in development mode — verbose logging enabled.');
}

if (process.env.NODE_ENV === 'production') {
  console.log('Running in production mode — optimized for performance.');
}

Common values are development, test, and production. Libraries like Express and Mongoose also use NODE_ENV internally to adjust their behavior.

Setting Environment Variables in Production

In production environments (like a cloud server), environment variables are configured in the hosting platform's dashboard — not in a .env file. Common platforms include:

  • Heroku: Set via the dashboard under Config Vars, or using the CLI: heroku config:set KEY=VALUE
  • Railway: Set under the environment variables section of the project.
  • AWS / Azure / GCP: Use their respective secrets management services.
  • Vercel: Set in Project Settings → Environment Variables.

Validating Required Environment Variables on Startup

A good practice is to check that all required environment variables are present before the application starts:

require('dotenv').config();

const requiredVars = ['PORT', 'DB_URI', 'JWT_SECRET'];

requiredVars.forEach(function(varName) {
  if (!process.env[varName]) {
    console.error(`ERROR: Missing required environment variable: ${varName}`);
    process.exit(1); // Stop the application
  }
});

console.log('All required environment variables are set. Starting app...');

This prevents the application from starting in a broken state and provides a clear error message about what is missing.

Key Points

  • Environment variables store sensitive and environment-specific configuration outside the codebase.
  • Access all environment variables in Node.js through the process.env object.
  • The dotenv package loads variables from a .env file into process.env at startup.
  • Always call require('dotenv').config() at the very top of the entry file.
  • The .env file must be added to .gitignore and never committed to version control.
  • Provide a .env.example template file so collaborators know which variables are needed.
  • In production, environment variables are set in the hosting platform's settings — not in a .env file.
  • Always validate required variables on startup to catch configuration errors early.

Leave a Comment

Your email address will not be published. Required fields are marked *