Environment Variables: Complete Guide for Developers (2026)
Published February 5, 2026 • 14 min read
Environment variables are key-value pairs that configure your applications without hardcoding values. They're essential for managing API keys, database URLs, and configuration across different environments (development, staging, production). This guide covers everything you need to know.
What Are Environment Variables?
Environment variables are dynamic values that can affect how processes behave on a computer. They exist outside your application code and can be changed without modifying your codebase.
Why Use Environment Variables?
- Security: Keep secrets out of source code
- Flexibility: Change configuration without redeploying
- Portability: Same code works in different environments
- 12-Factor App compliance: Separate config from code
Linux & macOS
View Environment Variables
# View all environment variables
printenv
env
# View specific variable
echo $HOME
echo $PATH
printenv HOME
Set Environment Variables (Session)
# Set for current session (lost on logout)
export API_KEY="your-api-key-here"
export DATABASE_URL="postgresql://localhost/mydb"
# Use the variable
echo $API_KEY
Set Environment Variables (Permanent)
# Bash (~/.bashrc or ~/.bash_profile)
echo 'export API_KEY="your-api-key"' >> ~/.bashrc
source ~/.bashrc
# Zsh (~/.zshrc)
echo 'export API_KEY="your-api-key"' >> ~/.zshrc
source ~/.zshrc
# System-wide (/etc/environment)
sudo echo 'API_KEY="your-api-key"' >> /etc/environment
Unset Environment Variables
unset API_KEY
Set for Single Command
# Run command with specific environment
API_KEY="temp-key" node app.js
# Multiple variables
API_KEY="key1" DATABASE_URL="db-url" npm start
Windows
View Environment Variables (CMD)
REM View all
set
REM View specific
echo %PATH%
echo %USERPROFILE%
View Environment Variables (PowerShell)
# View all
Get-ChildItem Env:
# View specific
$env:PATH
echo $env:USERPROFILE
Set Environment Variables (CMD)
REM Session only
set API_KEY=your-api-key
REM Permanent (user)
setx API_KEY "your-api-key"
REM Permanent (system)
setx API_KEY "your-api-key" /M
Set Environment Variables (PowerShell)
# Session only
$env:API_KEY = "your-api-key"
# Permanent (user)
[System.Environment]::SetEnvironmentVariable('API_KEY', 'your-api-key', 'User')
# Permanent (system)
[System.Environment]::SetEnvironmentVariable('API_KEY', 'your-api-key', 'Machine')
GUI Method (Windows)
- Right-click "This PC" → Properties
- Advanced system settings
- Environment Variables button
- Add/Edit variables under User or System
.env Files
What is a .env File?
A .env file stores environment variables in a key-value format. It's the standard way to manage configuration in modern development.
Example .env File
# .env
NODE_ENV=development
PORT=3000
API_KEY=your-api-key-here
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
SECRET_KEY=super-secret-key
REDIS_URL=redis://localhost:6379
# Comments are allowed
# Quotes are optional for simple values
Important: Never Commit .env Files!
# .gitignore
.env
.env.local
.env.*.local
Example .env File (Commit This)
# .env.example
NODE_ENV=development
PORT=3000
API_KEY=your-api-key-here
DATABASE_URL=postgresql://localhost:5432/mydb
SECRET_KEY=generate-random-secret
Node.js / JavaScript
Using dotenv Package
# Install
npm install dotenv
# Or
yarn add dotenv
// app.js
require('dotenv').config();
console.log(process.env.API_KEY);
console.log(process.env.DATABASE_URL);
// With custom path
require('dotenv').config({ path: '/custom/path/.env' });
ES6 Import
import 'dotenv/config';
console.log(process.env.API_KEY);
Access Environment Variables
const apiKey = process.env.API_KEY;
const port = process.env.PORT || 3000; // Default value
// Check if variable exists
if (!process.env.DATABASE_URL) {
throw new Error('DATABASE_URL is required');
}
Python
Using python-dotenv
# Install
pip install python-dotenv
# app.py
import os
from dotenv import load_dotenv
# Load .env file
load_dotenv()
# Access variables
api_key = os.getenv('API_KEY')
database_url = os.getenv('DATABASE_URL')
# With default value
port = int(os.getenv('PORT', 5000))
# Raise error if missing
secret = os.environ['SECRET_KEY'] # Raises KeyError if missing
Without dotenv Package
import os
api_key = os.getenv('API_KEY')
database_url = os.environ.get('DATABASE_URL')
PHP
Using vlucas/phpdotenv
# Install
composer require vlucas/phpdotenv
<?php
require __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$apiKey = $_ENV['API_KEY'];
$dbUrl = $_ENV['DATABASE_URL'];
// With default
$port = $_ENV['PORT'] ?? 3000;
Native PHP
<?php
$apiKey = getenv('API_KEY');
$dbUrl = $_ENV['DATABASE_URL'];
$port = $_SERVER['PORT'] ?? 8000;
Ruby
Using dotenv Gem
# Gemfile
gem 'dotenv'
# Install
bundle install
# config/application.rb
require 'dotenv'
Dotenv.load
api_key = ENV['API_KEY']
database_url = ENV['DATABASE_URL']
Docker
Pass Environment Variables
# Single variable
docker run -e API_KEY="your-key" my-app
# Multiple variables
docker run -e API_KEY="key" -e DATABASE_URL="url" my-app
# From file
docker run --env-file .env my-app
docker-compose.yml
version: '3.8'
services:
web:
image: my-app
environment:
- NODE_ENV=production
- API_KEY=${API_KEY} # From host .env
env_file:
- .env # Load entire file
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: npm run deploy
Set secrets: GitHub Repository → Settings → Secrets → Actions → New repository secret
Vercel
# Via CLI
vercel env add API_KEY
# Via dashboard
Project Settings → Environment Variables → Add
# Pull environment to local
vercel env pull
Netlify
# Via CLI
netlify env:set API_KEY your-key
# Via dashboard
Site Settings → Environment variables → Add variable
Heroku
# Set variable
heroku config:set API_KEY=your-key
# View all
heroku config
# View specific
heroku config:get API_KEY
# Unset
heroku config:unset API_KEY
# From .env file
heroku config:push
AWS Lambda
# Via AWS CLI
aws lambda update-function-configuration \
--function-name my-function \
--environment Variables="{API_KEY=your-key,DATABASE_URL=url}"
# Via console
Lambda → Configuration → Environment variables → Edit
Best Practices
Security
- Never commit .env files: Add to .gitignore
- Use .env.example: Document required variables
- Rotate secrets regularly: Change API keys periodically
- Use different keys per environment: Separate dev/staging/prod keys
- Encrypt sensitive data: Use secret management tools for production
Organization
- Group related variables: Use prefixes like
DB_,AWS_ - Use UPPER_SNAKE_CASE: Standard naming convention
- Document variables: Add comments in .env.example
- Validate required variables: Check on app startup
Development
- Create .env.example: Template for team members
- Use different .env files: .env.development, .env.test, .env.production
- Provide sensible defaults: Fallback values for optional config
- Log missing variables: Clear error messages
Common Environment Variables
Node.js
NODE_ENV=development # development, production, test
PORT=3000
API_KEY=your-api-key
DATABASE_URL=postgresql://...
REDIS_URL=redis://...
JWT_SECRET=your-secret
LOG_LEVEL=debug # error, warn, info, debug
CORS_ORIGIN=http://localhost:3000
Python / Django
DEBUG=True
SECRET_KEY=your-secret-key
DATABASE_URL=postgresql://...
ALLOWED_HOSTS=localhost,example.com
REDIS_URL=redis://...
Database URLs
# PostgreSQL
DATABASE_URL=postgresql://user:pass@host:5432/dbname
# MySQL
DATABASE_URL=mysql://user:pass@host:3306/dbname
# MongoDB
DATABASE_URL=mongodb://user:pass@host:27017/dbname
# SQLite
DATABASE_URL=sqlite:///./database.db
Validation Example
// config.js
require('dotenv').config();
const requiredEnvVars = [
'DATABASE_URL',
'API_KEY',
'SECRET_KEY'
];
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
throw new Error(`Missing required environment variable: ${envVar}`);
}
}
module.exports = {
database: process.env.DATABASE_URL,
apiKey: process.env.API_KEY,
secretKey: process.env.SECRET_KEY,
port: parseInt(process.env.PORT || '3000'),
nodeEnv: process.env.NODE_ENV || 'development',
isDev: process.env.NODE_ENV !== 'production'
};
Secret Management Tools
For production environments, consider using dedicated secret management:
- AWS Secrets Manager: Managed secrets for AWS
- HashiCorp Vault: Enterprise-grade secret storage
- Azure Key Vault: Azure's secret management
- Google Secret Manager: GCP secret storage
- Doppler: Universal secrets manager
- 1Password for Teams: Developer credential management
Troubleshooting
Variables Not Loading
# Check if dotenv is loaded
require('dotenv').config();
console.log(process.env); // Log all variables
# Check file location
console.log(require('path').resolve('.env'));
# Try absolute path
require('dotenv').config({ path: '/full/path/to/.env' });
Variables Empty in Production
- Ensure platform-specific setup (Vercel, Netlify, etc.)
- Check if variables are set in deployment dashboard
- Verify build process includes environment variables
- Check if variables need to be prefixed (e.g.,
REACT_APP_)
Framework-Specific Notes
Next.js
# Server-side only
DATABASE_URL=...
# Exposed to browser (prefix required)
NEXT_PUBLIC_API_URL=https://api.example.com
Create React App
# Must start with REACT_APP_
REACT_APP_API_KEY=your-key
REACT_APP_API_URL=https://api.example.com
# Access in React
const apiKey = process.env.REACT_APP_API_KEY;
Vite
# Must start with VITE_
VITE_API_KEY=your-key
VITE_API_URL=https://api.example.com
# Access in app
const apiKey = import.meta.env.VITE_API_KEY;
Conclusion
Environment variables are fundamental to modern application development. Master them to:
- Keep secrets secure and out of version control
- Easily configure apps across environments
- Follow 12-factor app principles
- Simplify deployment and collaboration
Start with simple .env files for local development, then graduate to secret management tools for production. Always validate required variables on app startup and document your configuration in .env.example.
More Configuration Guides
Check out our Docker Commands Cheat Sheet and Git Commands Guide for more deployment essentials.