Claude-skill-registry designing-zod-schemas

Designs Zod schemas following Zod-first development. Creates validation schemas, branded types, discriminated unions, and transforms. Infers TypeScript types from schemas. Triggers on: Zod schema, z.object, z.infer, validation, branded types, discriminated union, safeParse, refinement.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/designing-zod-schemas" ~/.claude/skills/majiayu000-claude-skill-registry-designing-zod-schemas && rm -rf "$T"
manifest: skills/data/designing-zod-schemas/SKILL.md
source content

Zod Schema Designer

Purpose

Guide the design and implementation of Zod schemas following the project's Zod-first development approach, where schemas are defined before implementing business logic.

When to Use

  • Creating new data structures
  • Adding validation to inputs
  • Designing configuration schemas
  • Implementing type-safe transformations
  • Creating test data builders

Table of Contents

Core Principles

Zod-First Development

  1. Define Schema First: Schema is the source of truth
  2. Infer Types: Use
    z.infer<>
    instead of manual type definitions
  3. Share Validation: Same schema for runtime validation and tests
  4. Compose Schemas: Build complex schemas from primitives

Decision Guide

NeedPatternExample
Basic validationPrimitives
z.string().min(1)
Domain safetyBranded types
transform((v) => v as EntitySlug)
Multiple typesDiscriminated union
z.discriminatedUnion('type', [...])
Cross-field rulesRefinement
.refine((data) => ...)
Data normalizationTransform
.transform((v) => v.trim())
Partial updatesPartial schema
Schema.partial()

Quick Reference

Common Schema Shapes

import { z } from 'zod';

// String with constraints
const NameSchema = z.string().min(1).max(100).trim();

// Slug pattern
const SlugSchema = z.string().regex(/^[a-z0-9-]+$/);

// Number with range
const PriceSchema = z.number().min(0).multipleOf(0.01);

// Object schema
const EntitySchema = z.object({
  name: z.string().min(1),
  slug: z.string().regex(/^[a-z0-9-]+$/),
  description: z.string().optional(),
});

// Array with validation
const TagsSchema = z.array(z.string()).min(1).max(10);

// Type inference
type Entity = z.infer<typeof EntitySchema>;

Safe Parsing

const result = schema.safeParse(data);

if (!result.success) {
  // Handle errors
  console.error(result.error.issues);
} else {
  // Use validated data
  const validData = result.data;
}

Schema Patterns

For detailed patterns and examples, see:

Project Schema Location

src/modules/config/schema/
├── schema.ts           # Main configuration schema
├── primitives.ts       # Reusable primitive schemas
├── entities/           # Entity-specific schemas
│   ├── category.ts
│   ├── product.ts
│   └── ...
└── index.ts            # Schema exports

Validation Checkpoints

PhaseValidateCommand
Schema definedNo TS errors
npx tsc --noEmit
Types inferred
z.infer
works
Check type in IDE
Validation works
safeParse
tests
pnpm test

Common Mistakes

MistakeIssueFix
Manual type definitionsType driftUse
z.infer<typeof Schema>
Using
.parse()
directly
Throws on invalidUse
.safeParse()
for error handling
Missing
.optional()
Runtime errorsMark optional fields explicitly
Complex refinementsHard to debugBreak into smaller schemas
Not using branded typesType confusionUse
.brand()
or transform for domain safety

External Documentation

For up-to-date Zod patterns, use Context7 MCP:

mcp__context7__get-library-docs with context7CompatibleLibraryID: "/colinhacks/zod"

References

  • {baseDir}/src/modules/config/schema/schema.ts
    - Main schema definitions
  • {baseDir}/docs/CODE_QUALITY.md#zod-first-development
    - Quality standards
  • Zod documentation: https://zod.dev

Related Skills

  • Complete entity workflow: See
    adding-entity-types
    for full schema-to-service implementation
  • Testing schemas: See
    analyzing-test-coverage
    for test data builders
  • GraphQL type mapping: See
    writing-graphql-operations
    for schema-to-GraphQL patterns

Quick Reference Rule

For a condensed quick reference, see

.claude/rules/config-schema.md
(automatically loaded when editing
src/modules/config/**/*.ts
files).