Environment Variables Best Practices
Learn how to securely manage .env files and environment variables. Protect your configuration secrets from accidental exposure.
Why .env Security Matters
Environment files often contain database passwords, API keys, and authentication secrets. A single exposed .env file can compromise your entire application, leading to data breaches, unauthorized access, and financial loss.
Common Mistakes to Avoid
Committing .env to Version Control
The most common mistake. Once committed, secrets remain in git history forever, even after deletion. Attackers scan repositories for leaked credentials.
Using Production Secrets in Development
Development environments are less secure. Using production credentials locally risks exposure through debug logs, error messages, or shared machines.
Hardcoding Fallback Values
Using default values like `process.env.API_KEY || 'default-key'` can accidentally expose test credentials or cause production to use insecure defaults.
Sharing .env Files Insecurely
Sending .env contents via Slack, email, or shared documents leaves secrets searchable and archived in multiple systems indefinitely.
Best Practices with Examples
Always Add .env to .gitignore
The first thing to do in any project. Create a .gitignore file and add .env, .env.local, .env.*.local to prevent accidental commits.
# .gitignore
.env
.env.local
.env.*.local
.env.development
.env.productionCreate .env.example Template
Maintain a .env.example file with all required variables but placeholder values. This documents what's needed without exposing secrets.
# .env.example
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
API_KEY=your-api-key-here
JWT_SECRET=generate-a-secure-secretUse Environment-Specific Files
Separate configurations for different environments. Use .env.development, .env.staging, .env.production with appropriate secrets for each.
# File structure
.env # Shared defaults
.env.local # Local overrides (gitignored)
.env.development # Development settings
.env.production # Production settingsValidate Required Variables
Check that all required environment variables are set at startup. Fail fast with clear error messages rather than encountering undefined errors later.
// Validate at startup
const required = ['DATABASE_URL', 'API_KEY'];
for (const key of required) {
if (!process.env[key]) {
throw new Error(`Missing env: ${key}`);
}
}Never Log Environment Variables
Avoid logging process.env or individual secrets. Logs are often stored, aggregated, and accessed by multiple systems and team members.
// Bad - exposes secrets in logs
console.log(process.env);
console.log('API Key:', process.env.API_KEY);
// Good - log only non-sensitive info
console.log('Environment:', process.env.NODE_ENV);Use Secrets Manager in Production
For production deployments, use platform-native secrets management instead of .env files. AWS Secrets Manager, Azure Key Vault, or Vercel Environment Variables.
# Platform examples
# Vercel: Project Settings → Environment Variables
# AWS: Secrets Manager or Parameter Store
# Heroku: Config Vars
# Docker: Docker secrets or env_fileRecommended Project Structure
| File | Purpose | Git |
|---|---|---|
.env | Shared defaults (optional, gitignored) | Ignored |
.env.local | Local overrides with real secrets | Ignored |
.env.example | Template with placeholder values | Tracked |
.env.development | Development environment config | Ignored |
.env.production | Production config (if needed locally) | Ignored |
.gitignore | Lists all .env files to ignore | Tracked |
Quick Reference: Do's and Don'ts
Do
- Add .env to .gitignore before your first commit
- Create .env.example with placeholder values
- Use different secrets for each environment
- Validate required variables at application startup
- Use platform secrets management for production
- Share .env contents via self-destructing links
- Rotate secrets periodically and after team changes
- Document all required variables in README or .env.example
Don't
- Commit .env files to version control
- Use production secrets in development
- Log environment variables or their values
- Share .env contents via Slack, email, or docs
- Use the same secrets across all environments
- Hardcode fallback values for secrets
- Store .env files in cloud drives or shared folders
- Ignore .env.example when it needs updating
When You Need to Share .env Contents
Sometimes sharing environment variables is unavoidable—onboarding new developers, working with contractors, or collaborating across teams. When you must share, use secure, self-destructing links instead of chat or email.
- One-time access prevents secrets from lingering in message history
- End-to-end encryption ensures only the recipient sees the content
- Automatic destruction means no manual cleanup needed
Need to Share Environment Variables?
When you need to share .env contents with a teammate or collaborator, use SnapPwd to create a secure, self-destructing link. No signup required.
Share .env Securely