What Are Environment Variables and Why Does My App Need Them?
What Are Environment Variables?
Environment variables are dynamic values that exist outside your application code but can be accessed by your running application. Think of them as a secure, flexible way to configure your app without hardcoding sensitive information or deployment-specific settings directly into your source code.
If you've ever wondered why your AI-generated app works perfectly in development but breaks in production, environment variables are probably the missing piece.
The Problem: Hardcoded Values Kill Flexibility
Let's say you're building a killer SaaS app with Claude's help. Your code might look something like this:
const dbConnection = {
host: 'localhost',
port: 5432,
database: 'my_app_dev',
username: 'dev_user',
password: 'super_secret_123'
};
const stripe = new Stripe('sk_test_abc123...');
const apiUrl = 'http://localhost:3000/api';
This works great on your laptop, but what happens when you deploy to production? You'd need different database credentials, a live Stripe key, and a production API URL. Without environment variables, you'd either:
- Hardcode production values (security nightmare)
- Manually change code for each deployment (error-prone)
- Commit secrets to your repo (please don't)
Environment Variables to the Rescue
With environment variables, your code becomes deployment-agnostic:
const dbConnection = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
database: process.env.DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD
};
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const apiUrl = process.env.API_URL;
Now your app reads configuration from the environment, making it portable across different deployment stages.
Common Use Cases for Environment Variables
1. Database Connections
Different environments need different databases:
- Development: Local PostgreSQL
- Staging: Shared test database
- Production: High-performance production cluster
2. API Keys and Secrets
Never commit these to your repo:
- Payment processor keys (Stripe, PayPal)
- Email service credentials (SendGrid, Mailgun)
- Third-party API tokens (OpenAI, Google Maps)
- JWT signing secrets
3. Feature Flags
Control features without redeploying:
const ENABLE_PREMIUM_FEATURES = process.env.ENABLE_PREMIUM === 'true';
const MAX_UPLOAD_SIZE = parseInt(process.env.MAX_UPLOAD_SIZE) || 10485760;
4. Environment-Specific URLs
- Development:
http://localhost:3000 - Staging:
https://staging.yourapp.com - Production:
https://yourapp.com
Setting Environment Variables
Development (.env files)
Create a .env file in your project root:
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=my_app_dev
DB_USER=dev_user
DB_PASSWORD=dev_password
# APIs
STRIPE_SECRET_KEY=sk_test_abc123...
OPENAI_API_KEY=sk-...
# App Config
NODE_ENV=development
PORT=3000
API_URL=http://localhost:3000/api
Important: Add .env to your .gitignore file!
# .gitignore
.env
.env.local
.env.*.local
Loading Environment Variables in Node.js
Use the dotenv package:
npm install dotenv
// At the top of your main file
require('dotenv').config();
// Now you can use process.env.VARIABLE_NAME
console.log(process.env.DB_HOST);
Production Deployment
In production, set environment variables through your hosting platform:
# Command line
export DB_HOST=prod-db.example.com
export STRIPE_SECRET_KEY=sk_live_real_key
# Or via your deployment platform's dashboard
Best Practices for Environment Variables
1. Use Descriptive Names
# Good
DB_HOST=localhost
STRIPE_SECRET_KEY=sk_test_123
MAX_UPLOAD_SIZE_MB=10
# Bad
H=localhost
KEY=sk_test_123
SIZE=10
2. Provide Sensible Defaults
const port = process.env.PORT || 3000;
const nodeEnv = process.env.NODE_ENV || 'development';
const maxRetries = parseInt(process.env.MAX_RETRIES) || 3;
3. Validate Critical Variables
if (!process.env.DATABASE_URL) {
throw new Error('DATABASE_URL environment variable is required');
}
if (!process.env.JWT_SECRET) {
throw new Error('JWT_SECRET must be set for security');
}
4. Group Related Variables
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
# Redis
REDIS_URL=redis://localhost:6379
REDIS_TTL=3600
# Email
EMAIL_FROM=noreply@myapp.com
SMTP_HOST=smtp.mailgun.org
Environment Variables in Different Frameworks
Next.js
Next.js has built-in environment variable support:
# .env.local
NEXT_PUBLIC_API_URL=http://localhost:3000/api
DATABASE_URL=postgresql://...
- Variables prefixed with
NEXT_PUBLIC_are exposed to the browser - Other variables are server-side only
React (Create React App)
# .env
REACT_APP_API_URL=http://localhost:3000/api
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_...
All variables must be prefixed with REACT_APP_.
Python/Django
import os
from django.conf import settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
'NAME': os.environ['DB_NAME'], # Required
'USER': os.environ['DB_USER'], # Required
'PASSWORD': os.environ['DB_PASSWORD'], # Required
}
}
Common Pitfalls to Avoid
1. Committing Secrets
Never commit .env files or hardcode secrets:
# Always add to .gitignore
.env
.env.local
.env.production
2. Not Setting Production Variables
Your app will crash if required environment variables are missing in production. Always double-check your deployment configuration.
3. Forgetting Type Conversion
// Environment variables are always strings
const port = process.env.PORT; // '3000' (string)
const maxRetries = process.env.MAX_RETRIES; // '5' (string)
// Convert when needed
const portNumber = parseInt(process.env.PORT) || 3000;
const isProduction = process.env.NODE_ENV === 'production';
const enableFeature = process.env.ENABLE_FEATURE === 'true';
Making Deployment Seamless
Environment variables are crucial for smooth deployments. They let you:
- Deploy the same code to multiple environments
- Update configuration without code changes
- Keep secrets secure and separate from source code
- Enable/disable features per environment
When you're shipping fast with AI-assisted development, environment variables ensure your brilliant code works everywhere, not just on your laptop.
Wrapping Up
Environment variables aren't just a deployment best practice - they're essential for building professional, maintainable applications. Whether you're using Claude to generate a React app or building a complex backend, proper environment variable usage will save you from deployment headaches and security nightmares.
Start using them in your next project, and your future self (and your ops team) will thank you.
Alex Hackney
DeployMyVibe