The Difference Between .env, .env.local, and .env.production
Modern frameworks support multiple .env file variants for different purposes. Understanding when to use each one is essential for proper configuration management.
The .env File Family
Before we dive into the specifics, let's understand the general purpose of each file type:
| File | Purpose | Commit to Git? |
|---|---|---|
| .env | Default values for all environments | Sometimes (with safe defaults) |
| .env.local | Local machine overrides with secrets | Never |
| .env.development | Development-specific values | Sometimes |
| .env.production | Production-specific values | Rarely (prefer platform settings) |
| .env.example | Template with placeholder values | Always |
Next.js Environment Files
Next.js has one of the most comprehensive .env file systems. Files are loaded in a specific order, with later files overriding earlier ones:
Key Rules for Next.js
.env.localis NOT loaded duringnext build- use .env.production.local instead- Test environment uses .env.test (not .env.local to ensure consistent test behavior)
- Only variables prefixed with
NEXT_PUBLIC_are exposed to the browser - Server-side variables are available in API routes, getServerSideProps, etc.
Example Setup
Vite Environment Files
Vite uses a similar system but with the VITE_ prefix instead of NEXT_PUBLIC_:
Accessing Variables in Vite
Custom modes can be used with vite build --mode stagingwhich will load .env.staging.
Create React App
CRA uses the REACT_APP_ prefix and has a simpler loading order:
Note: CRA embeds environment variables at build time, not runtime. Changing .env files requires a rebuild.
Best Practices
1. Keep Secrets Out of Version Control
Only commit files that don't contain actual secrets. Use .env.example for documentation:
2. Use .env.local for Personal Overrides
Each developer can have their own .env.local with personal settings (different database, test API keys, etc.) without affecting teammates.
3. Don't Use .env.production for Real Secrets
For production deployments, use your hosting platform's environment variable settings instead of .env.production files. This provides:
- Encryption at rest
- Access controls and audit logging
- No risk of accidental commits
- Easy rotation without code changes
4. Document Everything in .env.example
Always maintain a .env.example file that lists all required variables with comments explaining their purpose:
Common Mistakes to Avoid
- Using .env.local in CI/CD: Most frameworks skip .env.local in test/build environments. Use .env.production.local or platform-specific variables instead.
- Forgetting the prefix:Client-side variables must use the correct prefix (NEXT_PUBLIC_, VITE_, REACT_APP_) or they won't be available in the browser.
- Expecting runtime updates: Most frameworks embed env vars at build time. Changing .env requires a rebuild for changes to take effect.
- Mixing secrets with public vars: Keep secret server-only variables separate from public client-side variables to avoid accidental exposure.
Key Takeaways
- .env - Base configuration with safe defaults, often committed
- .env.local - Personal overrides with secrets, never committed
- .env.development/.env.production - Environment-specific values
- .env.example - Template documentation, always committed
- Later files override earlier files in the loading order
- Use platform settings for production secrets, not .env files