Environment Variables Best Practices

+15 Mana ✨

Introduction

Environment variables configure your app for different deployments. Mishandling them leads to security issues, broken builds, and frustrated developers.

Key Concepts

Variable types:

  • NEXT_PUBLIC_*: Exposed to browser (public)
  • Regular variables: Server-only (private)
  • Build-time vs runtime: When they're read

Deep Dive

Server vs Client Variables

bash
# .env.local

# Private - only available on server
DATABASE_URL="postgresql://..."
STRIPE_SECRET_KEY="sk_live_..."

# Public - exposed to browser
NEXT_PUBLIC_API_URL="https://api.example.com"
NEXT_PUBLIC_ANALYTICS_ID="UA-123456"

Validation at Startup

typescript
// lib/env.ts
import { z } from 'zod';

const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
  NEXT_PUBLIC_API_URL: z.string().url(),
});

export const env = envSchema.parse(process.env);

Per-Environment Files

.env                # Default
.env.local          # Local overrides (gitignored)
.env.development    # Development defaults
.env.production     # Production defaults

Summary

Prefix client-side variables with NEXT_PUBLIC_, validate variables at startup, and use .env.local for secrets. Never commit secrets to git.

✓ Completed