process.env
In Node.js, environment variables are accessed through process.env. Instead of hardcoding sensitive information such as database credentials or API keys directly in your code, it is common practice to pass them in as environment variables from outside the application.
process.env — Reading Environment Variables
Environment variables are key-value pairs set when a process starts. You can retrieve a value as a string using process.env.KEY_NAME. A key that does not exist returns undefined.
read_env.js
// Read environment variables
// Use a default value when a variable is not set (|| operator)
var dbHost = process.env.DB_HOST || 'localhost';
var dbPort = process.env.DB_PORT || '5432';
var apiKey = process.env.API_KEY;
console.log('DB_HOST:', dbHost);
console.log('DB_PORT:', dbPort);
// Treat a missing required environment variable as an error
if (!apiKey) {
console.error('Error: API_KEY is not set');
process.exit(1);
}
console.log('API key retrieved (length:', apiKey.length, ')');
DB_HOST=kira-db.example.com API_KEY=death_note_secret node read_env.js DB_HOST: kira-db.example.com DB_PORT: 5432 API key retrieved (length: 17 )
NODE_ENV — Switching Runtime Environments
NODE_ENV is a widely used conventional environment variable for distinguishing between runtime environments (development, production, test). Many frameworks and libraries read this value to switch their behavior.
node_env.js
// Switch runtime environment using NODE_ENV
var env = process.env.NODE_ENV || 'development';
var config = {
development: {
dbUrl: 'postgresql://localhost:5432/kira_dev',
debug: true
},
production: {
dbUrl: process.env.DATABASE_URL,
debug: false
}
};
var currentConfig = config[env] || config.development;
console.log('Environment:', env);
console.log('Debug mode:', currentConfig.debug);
console.log('DB URL:', currentConfig.dbUrl);
NODE_ENV=production DATABASE_URL=postgresql://prod-server/kira node node_env.js Environment: production Debug mode: false DB URL: postgresql://prod-server/kira
.env Files and the dotenv Package
Passing environment variables on the command line every time can be tedious. The dotenv package lets you write values in a .env file at the project root and have them loaded into process.env automatically.
npm install dotenv
.env
# Database settings for the note application # Add this file to .gitignore and never include it in the repository DB_HOST=localhost DB_PORT=5432 DB_NAME=death_note DB_USER=yagami DB_PASSWORD=secret_password_123 API_KEY=kira_api_key_xyz NODE_ENV=development
app.js
// Load dotenv at the top of the script
// The contents of the .env file are added to process.env
require('dotenv').config();
// Values written in .env are now accessible
console.log('DB_HOST:', process.env.DB_HOST);
console.log('DB_NAME:', process.env.DB_NAME);
console.log('NODE_ENV:', process.env.NODE_ENV);
node app.js DB_HOST: localhost DB_NAME: death_note NODE_ENV: development
.env File Syntax Rules
| Notation | Example | Description |
|---|---|---|
| Basic form | KEY=value | Separate the key and value with = and no spaces. |
| Double quotes | KEY="hello world" | Wrap values containing spaces in double quotes. |
| Single quotes | KEY='raw value' | Treated as a literal string without variable expansion. |
| Comment | # comment text | Lines starting with # are treated as comments and ignored. |
| Empty line | (blank line) | Empty lines are ignored. |
cross-env — Setting Environment Variables Cross-Platform
On macOS and Linux you can write NODE_ENV=production node app.js, but this syntax does not work on Windows. The cross-env package lets you use the same syntax regardless of operating system.
npm install --save-dev cross-env
package.json (scripts section)
{
"scripts": {
"start": "cross-env NODE_ENV=production node app.js",
"dev": "cross-env NODE_ENV=development node app.js",
"test": "cross-env NODE_ENV=test node test.js"
}
}
npm run start npm run dev
Security Considerations
| Consideration | Details |
|---|---|
| Keep .env out of git | Add .env to .gitignore so passwords and API keys do not remain in the repository. |
| Provide .env.example | Include a .env.example with empty values in the repository so other developers know which variables are required. |
| Do not log environment variables | Using console.log(process.env) to output the entire env object can expose API keys and other secrets. |
| Avoid .env in production | On production servers, set environment variables through the OS or container. Avoid placing .env files on the server. |
Sample Code — Validating Required Environment Variables
This sample validates at application startup that all required environment variables are set.
validate_env.js
require('dotenv').config();
// List of required environment variables
var required = ['DB_HOST', 'DB_PORT', 'DB_NAME', 'API_KEY', 'NODE_ENV'];
// Collect variables that are not set
var missing = required.filter(function(key) {
return !process.env[key];
});
// If any variables are missing, display the list and exit
if (missing.length > 0) {
console.error('The following environment variables are not set:');
missing.forEach(function(key) {
console.error(' - ' + key);
});
// Near: Logically, processing cannot continue without all variables set
process.exit(1);
}
console.log('All required environment variables are confirmed');
console.log('NODE_ENV:', process.env.NODE_ENV);
node validate_env.js The following environment variables are not set: - DB_HOST - API_KEY
Summary
process.env is an object for accessing environment variables passed in from the OS, shell, or container. All values are stored as strings, so when using a value as a number you must convert it with Number(process.env.PORT) or parseInt(process.env.PORT, 10).
The dotenv package simplifies environment variable management during development. In production, it is common to rely on infrastructure-level configuration (server environment variables, Docker's --env option, Kubernetes secrets, etc.) rather than a .env file.
Common Mistakes
Common Mistake 1: process.env.PORT is a string, so '3000' + 1 becomes '30001'
All environment variable values are stored as strings. Performing arithmetic directly results in string concatenation.
port_type.js (NG)
// NG: Adding 1 to a string PORT produces string concatenation var port = process.env.PORT + 1; console.log(port);
PORT=3000 node port_type.js 30001
process.env.PORT is the string '3000', so + 1 performs string concatenation rather than numeric addition, yielding '30001'.
port_type.js (OK)
// OK: Convert to a number explicitly with Number() before arithmetic var port = Number(process.env.PORT) + 1; console.log(port);
PORT=3000 node port_type.js 3001
When arithmetic is needed, convert explicitly to a numeric type using Number() or parseInt(process.env.PORT, 10).
Common Mistake 2: Committing the .env file to Git and leaking API keys
The .env file contains sensitive information such as passwords and API keys. Committing it to the repository makes it accessible to anyone with access to the repository.
Add .env to .gitignore to prevent it from being included in the repository.
.gitignore
# Do not include environment variable files in the repository .env .env.local .env.production
Include a .env.example with empty values in the repository so other developers know which variables are needed.
.env.example
# Copy this file to .env and fill in the actual values DB_HOST= DB_PORT=5432 DB_NAME= DB_USER= DB_PASSWORD= API_KEY= NODE_ENV=development
Do not write actual values in .env.example — only variable names and descriptions. Developers copy this file to create their own .env and fill in values for their environment.
If you find any errors or copyright issues, please contact us.