Use when you have a written implementation plan to execute in a separate session with review checkpoints
npx skills add soilmass/vibe-coding-plugin --skill "env-validation"
Install specific skill from multi-skill repository
# Description
>
# SKILL.md
name: env-validation
description: >
Environment variable validation β @t3-oss/env-nextjs + Zod schema, build-time validation, .env.example sync, runtime crash prevention
allowed-tools: Read, Grep, Glob
Environment Validation
Purpose
Build-time environment variable validation using @t3-oss/env-nextjs and Zod. Catches missing
or malformed env vars at build time instead of runtime. The ONE skill for environment safety.
When to Use
- Setting up env var validation for a new project
- Adding new environment variables
- Debugging "undefined" env var errors in production
- Syncing
.env.examplewith actual requirements
When NOT to Use
- Deployment configuration β
deploy - Security headers and CSP β
security - Secret management in CI/CD β
deploy
Pattern
Env schema with @t3-oss/env-nextjs
// src/env.ts
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
export const env = createEnv({
server: {
DATABASE_URL: z.string().url(),
AUTH_SECRET: z.string().min(32),
RESEND_API_KEY: z.string().startsWith("re_"),
},
client: {
NEXT_PUBLIC_APP_URL: z.string().url(),
},
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
AUTH_SECRET: process.env.AUTH_SECRET,
RESEND_API_KEY: process.env.RESEND_API_KEY,
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
},
});
Usage in code
// Server Component or Server Action
import { env } from "@/env";
const db = new PrismaClient({
datasourceUrl: env.DATABASE_URL, // Type-safe, validated
});
.env.example sync
# .env.example β committed to git, documents all required vars
DATABASE_URL=""
AUTH_SECRET=""
RESEND_API_KEY=""
NEXT_PUBLIC_APP_URL=""
Anti-pattern
// WRONG: non-null assertion β crashes at runtime if missing
const apiKey = process.env.API_KEY!;
// WRONG: no validation β silently undefined
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) throw new Error("Missing DATABASE_URL"); // Manual, error-prone
// CORRECT: validated at build time
import { env } from "@/env";
const dbUrl = env.DATABASE_URL; // Never undefined
Never use process.env.X! with non-null assertion. It compiles but crashes at runtime.
Common Mistakes
- Using
process.envdirectly without validation β undefined at runtime - Non-null assertion
!on env vars β hides missing variables - Client vars without
NEXT_PUBLIC_prefix β undefined in browser - Not updating
.env.examplewhen adding new variables - Putting server secrets in
clientschema β exposed in browser bundle
Checklist
- [ ]
@t3-oss/env-nextjsandzodinstalled - [ ]
src/env.tsdefines all env vars with Zod schemas - [ ] Server vs client vars properly separated
- [ ]
.env.examplematches env schema - [ ] All
process.envaccess goes throughenvimport - [ ] Build fails if env vars are missing (not runtime crash)
Composes With
deployβ env vars must be set in hosting platformsecurityβ validates secrets exist without exposing themscaffoldβ env validation is part of project setup
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.