Dotenv
Comprehensive guide to using dotenv for managing environment variables in Node.js applications, covering installation, configuration, security implications, and best practices.
In modern applications, it's critical to separate configuration data from code. This is where environment variables come in — allowing you to store configuration values like database credentials, API keys, and port numbers outside your codebase.
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env in Node.js applications.
Why Use Dotenv?
- Keeps sensitive data (e.g., API keys, database URLs) out of source code.
- Supports multiple environments (development, production, testing).
- Simplifies configuration management.
- Works cross-platform without needing system-level configuration.
Installing Dotenv
npm install dotenvCreating a .env File
The .env file contains key-value pairs representing environment variables.
Example .env file:
PORT=3000
DB_URI=mongodb://localhost:27017/my_database
API_KEY=supersecretapikey⚠️ Never commit
.envto version control. Add.envto your.gitignorefile.
Loading Environment Variables
At the very top of your main entry file (e.g., app.js, index.js), require and configure dotenv:
require('dotenv').config();
console.log(process.env.PORT); // Outputs: 3000
console.log(process.env.DB_URI); // Outputs: mongodb://localhost:27017/my_databaseOr using ES6 import syntax:
import dotenv from 'dotenv';
dotenv.config();Using Environment Variables
const express = require('express');
const app = express();
const PORT = process.env.PORT || 5000;
const dbUri = process.env.DB_URI;
app.get('/', (req, res) => {
res.send('Server running!');
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});Environment Variable Types
All variables from .env are loaded as strings. If you need to work with numbers or booleans, convert them explicitly:
const PORT = parseInt(process.env.PORT, 10) || 3000;
const IS_PRODUCTION = process.env.NODE_ENV === 'production';Example: Database Connection Using dotenv
const mongoose = require('mongoose');
require('dotenv').config();
const dbUri = process.env.DB_URI;
mongoose.connect(dbUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log('MongoDB connected'))
.catch(err => console.error('Database connection error:', err));Advanced Usage
Multiple Environment Files
Use different .env files per environment:
.env.development.env.production.env.test
Then load them selectively:
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
});Example startup command:
NODE_ENV=development node app.jsOverriding Environment Variables
You can pass variables when starting the process:
PORT=4000 node app.jsVariables passed via the CLI take precedence over .env values.
Security Implications
- Never commit
.envto version control. - Keep
.envfiles outside public folders. - Use environment-specific files for sensitive credentials.
- Consider services like Vault or AWS Secrets Manager for production-grade secret management.
Best Practices
- Use uppercase variable names:
API_KEY,DB_URI. - Document expected variables in a
.env.examplefile:
PORT=3000
DB_URI=mongodb://localhost:27017/my_database
API_KEY=your_api_key_here- Validate that required environment variables are present at runtime.
Example validation:
if (!process.env.DB_URI) {
throw new Error('Missing DB_URI environment variable');
}