← ClaudeAtlas

env-validationlisted

Validate environment variables at boot via Zod in @repo/core/env. Separate PUBLIC (NEXT_PUBLIC_*) from server-only. Fail fast at startup; never raw process.env in business code.
voidcorp-core/void-harness · ★ 0 · Code & Development · score 76
Install: claude install-skill voidcorp-core/void-harness
# env-validation Use when adding any new environment variable, or when working in a project that doesn't yet have `@repo/core/env`. Env vars are an invisible trust boundary — they're inputs from outside the process, and "the database URL is undefined" should explode at boot, not at the first query. This skill is the void-harness operational form. Composes with `harness:security-guidance` (env doctrine) and enforced by the `no-process-env-in-app` hook. ## The principle ``` process.env.X → used ONLY inside @repo/core/env import { env } from '@repo/core' → used everywhere else ``` `@repo/core/env` parses + validates `process.env` ONCE, exposes a typed object. Any business code reading `process.env` directly is forbidden (enforced by the `no-process-env-in-app` hook). ## The schema ```ts // packages/core/src/env.ts import { z } from 'zod'; const ServerSchema = z.object({ NODE_ENV: z.enum(['development', 'production', 'test']), DATABASE_URL: z.string().url(), STRIPE_SECRET_KEY: z.string().regex(/^sk_(test|live)_/), STRIPE_WEBHOOK_SECRET: z.string().min(10), SENTRY_DSN: z.string().url().optional(), OTEL_EXPORTER_OTLP_ENDPOINT: z.string().url().optional(), }); const ClientSchema = z.object({ NEXT_PUBLIC_APP_URL: z.string().url(), NEXT_PUBLIC_SENTRY_DSN: z.string().url().optional(), }); function parseEnv() { const isServer = typeof window === 'undefined'; const server = isServer ? ServerSchema.parse(process.env) : ({} as z.infer<typeof Server