| name | env-config-guidelines |
| description | Environment configuration guidelines for Node.js including variable naming, type-safe loading with Zod, secrets management, and feature flags. Auto-loaded when working with environment config. |
| category | guideline |
| user-invocable | false |
Environment Configuration Guidelines
Core Principles
- Fail fast - Validate configuration at startup
- No secrets in code - All secrets from environment
- Type safety - Parse and validate env vars
- Defaults where safe - Sensible defaults for non-sensitive values
- Documentation - Every variable documented
Environment Variable Naming
Naming Convention
APP_PORT={{DEFAULT_APP_PORT}}
APP_HOST={{DEFAULT_APP_HOST}}
APP_LOG_LEVEL=info
DATABASE_URL={{EXAMPLE_DATABASE_URL}}
DATABASE_POOL_SIZE=10
DATABASE_SSL_ENABLED=true
REDIS_URL=redis://{{DEFAULT_APP_HOST}}:{{DEFAULT_REDIS_PORT}}
STRIPE_API_KEY=sk_test_xxx
SENDGRID_API_KEY=SG.xxx
FEATURE_NEW_DASHBOARD=true
FEATURE_BETA_API=false
Naming Rules
DATABASE_URL
databaseUrl
database-url
SMTP_HOST
HOST
CACHE_TTL_SECONDS=300
REQUEST_TIMEOUT_MS=5000
MAX_FILE_SIZE_MB=10
Configuration Loading
Type-Safe Configuration with Zod
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
PORT: z.coerce.number().default({{DEFAULT_APP_PORT}}),
HOST: z.string().default('{{DEFAULT_APP_HOST}}'),
DATABASE_URL: z.string().url(),
STRIPE_API_KEY: z.string().startsWith('sk_'),
FEATURE_NEW_DASHBOARD: z.coerce.boolean().default(false),
});
function loadConfig() {
const result = envSchema.safeParse(process.env);
if (!result.success) {
console.error('Invalid environment configuration:');
console.error(result.error.format());
process.exit(1);
}
return result.data;
}
export const config = loadConfig();
export type Config = z.infer<typeof envSchema>;
Environment Files
File Structure
.env
.env.local
.env.development
.env.production
.env.test
.env.example
Loading Order
import { config } from 'dotenv';
import { expand } from 'dotenv-expand';
const env = process.env.NODE_ENV || 'development';
[
'.env',
'.env.local',
`.env.${env}`,
`.env.${env}.local`,
].forEach(file => {
expand(config({ path: file, override: true }));
});
References