Skip to content
Zod Validation logo

Zod Validation

> **Skill Purpose:** TypeScript-first schema validation and runtime type checking patterns

Coverage-Creatives/zeus0installs0stars

SKILL.md

Full skill instructions

Zod Validation

Skill Purpose: TypeScript-first schema validation and runtime type checking patterns


Core Skill Pattern

Objective: Establish type-safe data validation with runtime checking, TypeScript inference, and integration patterns for data integrity.

Universal Pattern:

  1. Define validation schemas with type inference
  2. Create validation patterns for different data contexts
  3. Set up error handling and validation reporting
  4. Establish integration patterns with data sources
  5. Create schema organization and maintenance procedures

Key Decisions (Project-Specific):

  • Validation strictness and error handling approach
  • Schema organization and naming conventions
  • Integration depth with data sources and APIs
  • Form validation vs API validation patterns
  • Error reporting and user feedback mechanisms

Project-Specific Implementation Notes

Customize per project:

  • Validation strictness based on data sensitivity and user experience
  • Schema organization based on project complexity and team size
  • Integration level based on data sources and API requirements
  • Error handling based on user interface needs
  • Form vs API validation separation based on architecture

Example Implementation (Zod with TypeScript Pattern)

Note: This is an example pattern using Zod. Adapt validation library and configuration based on your specific project requirements and type system needs.

Prerequisites (Example)

  • Project initialized with TypeScript
  • Validation requirements defined
  • Data sources and API contracts established

Example: Zod Validation Implementation

Framework-Specific Example: This demonstrates the pattern using Zod with TypeScript. Adapt for your validation library and type system.

1. Basic Schema Definition

import { z } from 'zod';

// Define schema
const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(1).max(100),
  role: z.enum(['admin', 'user', 'guest']),
  createdAt: z.date(),
});

// Infer TypeScript type
type User = z.infer<typeof UserSchema>;

2. Validation

// Parse (throws on error)
const user = UserSchema.parse(untrustedData);

// Safe parse (returns result object)
const result = UserSchema.safeParse(untrustedData);
if (result.success) {
  console.log(result.data);
} else {
  console.log(result.error.issues);
}

3. API Request Validation

// Request body schema
const CreateUserRequestSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
  password: z.string().min(8),
});

// In API route
export async function POST(request: Request) {
  const body = await request.json();
  const result = CreateUserRequestSchema.safeParse(body);
  
  if (!result.success) {
    return Response.json({ error: result.error.issues }, { status: 400 });
  }
  
  // result.data is typed and validated
  const { email, name, password } = result.data;
}

4. Form Validation (with react-hook-form)

import { zodResolver } from '@hookform/​resolvers/​zod';
import { useForm } from 'react-hook-form';

const FormSchema = z.object({
  email: z.string().email('Invalid email'),
  password: z.string().min(8, 'Password must be at least 8 characters'),
});

function MyForm() {
  const form = useForm({
    resolver: zodResolver(FormSchema),
  });
}

5. Database Type Alignment

// Align Zod schema with Supabase types
import { Database } from '@/​types/​database';

type DbUser = Database['public']['Tables']['users']['Row'];

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  // ... match database columns
}) satisfies z.ZodType<DbUser>;

File Organization

/​lib/​validations/
├── index.ts           # Re-exports all schemas
├── user.ts            # User-related schemas
├── auth.ts            # Auth-related schemas
└── [feature].ts       # Feature-specific schemas

Naming Conventions

TypeConventionExample
Schema[Entity]SchemaUserSchema
Request[Action][Entity]RequestSchemaCreateUserRequestSchema
Response[Action][Entity]ResponseSchemaGetUserResponseSchema
Form[Form]FormSchemaLoginFormSchema

Best Practices

  1. Co-locate schemas with usage - Keep validation schemas near the code that uses them
  2. Use safeParse for user input - Never trust external data
  3. Align with database types - Ensure Zod schemas match Supabase types
  4. Provide meaningful error messages - Use .message() for custom errors
  5. Compose schemas - Use .extend(), .pick(), .omit() for DRY schemas

Integration with Supabase

// Validate before insert
const validated = UserSchema.parse(userData);
const { data, error } = await supabase
  .from('users')
  .insert(validated);

// Validate after select
const { data } = await supabase.from('users').select('*');
const users = z.array(UserSchema).parse(data);

Stop Conditions

STOP and escalate if:

  • Schema doesn't align with database types
  • Validation requirements unclear
  • Complex nested validation needed without clear spec

Skill Version: 1.0.0