Zod Nested Environment Config
Flatten process.env into a strongly typed nested config with Zod, supporting defaults, optional sections, and fail-fast startup checks.
Code
import { z } from 'zod';
const ConfigSchema = z.object({
NODE_ENV: z.enum(['development', 'staging', 'production']),
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
DATABASE_URL: z.string().url(),
DATABASE_POOL_MAX: z.coerce.number().int().min(1).max(100).default(10),
REDIS_URL: z.string().url().optional(),
FEATURES: z.string().transform((raw, ctx) => {
const flags = raw.split(',').map((f) => f.trim()).filter(Boolean);
const known = ['audit', 'beta-ui', 'webhooks'] as const;
for (const f of flags) {
if (!known.includes(f as never)) {
ctx.addIssue({ code: 'custom', message: 'unknown feature flag: ' + f });
return z.NEVER;
}
}
return flags;
}).default(''),
});
type AppConfig = z.infer<typeof ConfigSchema>;
function loadConfig(source: Record<string, string | undefined>): AppConfig {
const parsed = ConfigSchema.safeParse(source);
if (!parsed.success) {
const report = parsed.error.issues
.map((i) => i.path.join('.') + ': ' + i.message)
.join('; ');
throw new Error('invalid environment configuration -> ' + report);
}
return parsed.data;
}
export const config = loadConfig(process.env as Record<string, string | undefined>);
export const isProd = config.NODE_ENV === 'production';Report a problem with this exampleOpens a pre-filled issue on GitHub.