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.production

Create .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-secret

Use 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 settings

Validate 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_file

Recommended Project Structure

FilePurposeGit
.envShared defaults (optional, gitignored)Ignored
.env.localLocal overrides with real secretsIgnored
.env.exampleTemplate with placeholder valuesTracked
.env.developmentDevelopment environment configIgnored
.env.productionProduction config (if needed locally)Ignored
.gitignoreLists all .env files to ignoreTracked

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