Skip to main content
skill CX Codex

zod · secondsky — Claude Code skill: what it does, how to install

Provides Zod 4 schema patterns and type inference rules for agent sessions. Useful when setting up API validation, environment configs, or v3 migrations.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add secondsky/claude-skills --skill zod -a claude-code
Open on GitHub

What zod does

The skill provides guidance for building runtime schemas and deriving TypeScript types with Zod 4.x. It covers primitive validations, .safeParse() checks, and JSON Schema generation for OpenAPI.

The reference focuses on modern APIs like top-level z.email(), z.codec(), and z.iso.datetime(). It also addresses migration tasks, highlighting the shift from deprecated .merge() to .extend() alongside new error helpers.

Schemas require TypeScript 5.5 or newer with "strict": true configured in tsconfig.json. Without strict mode enabled, static inference breaks down.

What it helps with

  • validate API request payloads and server responses
  • parse environment variables and configuration files safely
  • generate JSON Schema representations for OpenAPI specs
  • update legacy Zod v3 schemas to v4 conventions

Example prompts for the agent

  • Write a Zod 4 schema to validate user registration inputs
  • Show how to parse environment variables using safeParse
  • Migrate this schema from merge to extend using Zod 4 syntax

How to install zod

1Skills CLI (Vercel)

npx skills add secondsky/claude-skills --skill zod -a claude-code

2Manually: put the files in place

~/.claude/skills/zod/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/zod/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about zod

How to install zod in Claude Code?

Run npx skills add secondsky/claude-skills --skill zod -a claude-code. The file is saved to ~/.claude/skills/zod/SKILL.md.

Which Zod version does this skill target?

It targets Zod 4.x, recommending version 4.4.x. Features like z.codec() require at least Zod 4.1.

What are the TypeScript requirements?

You need TypeScript 5.5 or higher. The tsconfig.json file must also have "strict": true enabled.

Source text

SKILL.md · MIT
---
name: zod
description: TypeScript-first schema validation and type inference. Use for validating API requests/responses, form data, env vars, configs, defining type-safe schemas with runtime validation, transforming data, generating JSON Schema for OpenAPI/AI, or encountering missing validation errors, type inference issues, validation error handling problems. Zero dependencies, compact core (~5kb gzipped; zod/mini ~1.9kb).
license: MIT
metadata:
  version: 2.1.0
  last_verified: 2026-08-20
  package_version: 4.4.x
  keywords:
    - zod
    - validation
    - schema
    - typescript
    - type-safety
    - runtime-validation
    - type-inference
    - data-validation
    - form-validation
    - api-validation
    - json-schema
    - refinement
    - transformation
    - error-handling
    - parse
    - safeParse
    - z.object
    - z.string
    - z.number
    - z.array
    - z.union
    - z.discriminatedUnion
    - z.refine
    - z.transform
    - z.infer
    - z.coerce
    - z.enum
    - z.literal
    - z.tuple
    - z.record
    - z.intersection
    - z.codec
    - z.toJSONSchema
    - z.treeifyError
    - z.flattenError
    - z.prettifyError
    - z.registry
    - z.globalRegistry
    - .register
    - .meta
    - error-customization
    - localization
    - i18n
    - migration
    - v3-to-v4
    - breaking-changes
    - tRPC
    - prisma-zod
    - react-hook-form
    - trpc
    - environment-variables
    - env-validation
    - config-validation
    - dto
    - type-guard
    - runtime-type-checking
    - zod-mini
    - z.core
    - z.preprocess
    - z.custom
    - z.templateLiteral
    - z.catchall
    - z.check
    - z.file
    - z.json
    - z.stringbool
    - z.xor
    - z.exactOptional
    - z.safeExtend
    - z.fromJSONSchema
    - best-practices
    - performance
  token_savings: 65%
  errors_prevented: 8
  production_tested: true
  related_skills:
    - react-hook-form-zod
---

# Zod: TypeScript-First Schema Validation

## Overview

Zod is a TypeScript-first validation library that enables developers to define schemas for validating data at runtime while automatically inferring static TypeScript types. With zero dependencies and a compact core (~5kb gzipped; ~1.9kb for `zod/mini`), Zod provides immutable, composable validation with comprehensive error handling.

## Installation

```bash
bun add zod
# or
npm install zod
# or
pnpm add zod
# or
yarn add zod
```

**Requirements**:
- TypeScript v5.5+ with `"strict": true` in `tsconfig.json`
- Zod 4.x (4.4.x recommended; `z.codec()` requires 4.1+)

**Important**: This skill documents **Zod 4.x** features. The following APIs require Zod 4 and are NOT available in Zod 3.x:
- `z.codec()` - Bidirectional transformations
- `z.iso.date()`, `z.iso.time()`, `z.iso.datetime()`, `z.iso.duration()` - ISO format validators
- `z.toJSONSchema()` - JSON Schema generation
- `z.treeifyError()`, `z.prettifyError()`, `z.flattenError()` - New error formatting helpers
- `.meta()` - Enhanced metadata (Zod 3.x only has `.describe()`)
- Unified `error` parameter - Replaces `message`, `invalid_type_error`, `required_error`, `errorMap`
- `.check()` - Low-level multi-issue validation (composes check factories like `z.minLength(3)`)
- `z.file()`, `z.json()`, `z.stringbool()`, `z.xor()`, `z.templateLiteral()` - New schema types
- `z.exactOptional()`, `.prefault()`, `.safeExtend()`, `z.fromJSONSchema()` - New utilities

For Zod 3.x compatibility or migration guidance, see https://zod.dev

**Import paths** (all ship in the `zod` package):
- `import { z } from "zod"` — standard (v4 since 4.0)
- `import { z } from "zod/v4"` — pin for libraries supporting both v3 (3.25+) and v4 users
- `import { z } from "zod/mini"` — functional, tree-shakable API (~1.9kb; checks via `.check(z.minLength(3))`)
- `import * as core from "zod/v4/core"` — low-level `$`-prefixed internals for library authors

## Migrating from Zod v3 to v4

**Load `references/migration-guide.md` for complete v3 to v4 migration documentation.**

### Quick Summary

Zod v4 introduces breaking changes for better performance:

- **Error customization**: Use unified `error` parameter (replaces `message`, `invalid_type_error`, `required_error`)
- **Number validation**: Stricter - rejects `Infinity` and unsafe integers
- **String formats**: Prefer top-level functions (`z.email()` instead of `z.string().email()`; the method forms still work but are deprecated)
- **Object defaults**: Applied even in optional fields
- **Deprecated APIs**: Use `.extend()` (not `.merge()`), `z.treeifyError()` (not `error.format()`)
- **Function validation**: Use `.implement()` method
- **UUID validation**: Stricter RFC 9562/4122 compliance

**→ Load `references/migration-guide.md` for:** Complete breaking changes, migration checklist, gradual migration strategy, rollback instructions

## Core Concepts

### Basic Usage Pattern

```typescript
import { z } from "zod";

// Define schema
const UserSchema = z.object({
  username: z.string(),
  age: z.number().int().positive(),
  email: z.email(),
});

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

// Validate data (throws on error)
const user = UserSchema.parse(data);

// Validate data (returns result object)
const result = UserSchema.safeParse(data);
if (result.success) {
  console.log(result.data); // Typed!
} else {
  console.error(result.error); // ZodError
}
```

### Parsing Methods

Use the appropriate parsing method based on error handling needs:

- **`.parse(data)`** - Throws `ZodError` on invalid input; returns strongly-typed data on success
- **`.safeParse(data)`** - Returns `{ success: true, data }` or `{ success: false, error }` (no exceptions)
- **`.parseAsync(data)`** - For schemas with async refinements/transforms
- **`.safeParseAsync(data)`** - Async version that doesn't throw

**Best Practice**: Use `.safeParse()` to avoid try-catch blocks and leverage discriminated unions.

## Primitive Types

### Strings

```typescript
z.string()                    // Basic string
z.string().min(5)            // Minimum length
z.string().max(100)          // Maximum length
z.string().length(10)        // Exact length
z.email()                    // Email validation (top-level in v4)
z.url()                      // URL validation (top-level in v4)
z.uuid()                     // UUID (RFC 9562; use z.guid() for permissive)
z.uuidv4()                   // Version-specific UUIDs (also z.uuidv7)
z.httpUrl()                  // http/https URLs only (rejects ftp:// etc.)
z.e164()                     // Phone numbers (E.164 format)
z.string().regex(/^\d+$/)    // Custom pattern
z.string().startsWith("pre") // Prefix check
z.string().endsWith("suf")   // Suffix check
z.string().trim()            // Auto-trim whitespace
z.string().toLowerCase()     // Auto-lowercase
z.string().toUpperCase()     // Auto-uppercase

// ISO formats (Zod 4+)
z.iso.date()                 // YYYY-MM-DD
z.iso.time()                 // HH:MM:SS
z.iso.datetime()             // ISO 8601 datetime
z.iso.duration()             // ISO 8601 duration

// Network formats
z.ipv4()                     // IPv4 address
z.ipv6()                     // IPv6 address
z.cidrv4()                   // IPv4 CIDR notation
z.cidrv6()                   // IPv6 CIDR notation

// Other formats
z.jwt()                      // JWT token
z.nanoid()                   // Nanoid
z.cuid()                     // CUID
z.cuid2()                    // CUID2
z.ulid()                     // ULID
z.base64()                   // Base64 encoded
z.hex()                      // Hexadecimal
z.hash("sha256")             // Hash of algorithm-specific length
z.guid()                     // Permissive UUID/GUID (non-RFC)
z.hostname()                 // Hostname
z.mac()                      // MAC address
z.uuid({ version: "v4" })    // UUID with version constraint
z.email({ pattern: z.regexes.email }) // Email with explicit pattern
```

### Numbers

```typescript
z.number()                   // Basic number
z.number().int()             // Integer only
z.number().positive()        // > 0
z.number().nonnegative()     // >= 0
z.number().negative()        // < 0
z.number().nonpositive()     // <= 0
z.number().min(0)            // Minimum value
z.number().max(100)          // Maximum value
z.number().gt(0)             // Greater than
z.number().gte(0)            // Greater than or equal
z.number().lt(100)           // Less than
z.number().lte(100)          // Less than or equal
z.number().multipleOf(5)     // Must be multiple of 5
z.int()                      // Shorthand for z.number().int()
z.int32()                    // 32-bit integer (also z.uint32, z.int64, z.uint64)
z.float32()                  // 32-bit float (also z.float64)
z.nan()                      // NaN value
```

### Coercion (Type Conversion)

```typescript
z.coerce.string()            // Convert to string
z.coerce.number()            // Convert to number
z.coerce.boolean()           // Convert to boolean
z.coerce.bigint()            // Convert to bigint
z.coerce.date()              // Convert to Date

// Example: Parse query parameters
const QuerySchema = z.object({
  page: z.coerce.number().int().positive(),
  limit: z.coerce.number().int().max(100).default(10),
});

// "?page=5&limit=20" -> { page: 5, limit: 20 }
```

### Other Primitives

```typescript
z.boolean()                  // Boolean
z.date()                     // Date object
z.date().min(new Date("2020-01-01"))
z.date().max(new Date("2030-12-31"))
z.bigint()                   // BigInt
z.symbol()                   // Symbol
z.null()                     // Null
z.undefined()                // Undefined
z.void()                     // Void (undefined)

// File validation (v4) — sizes are bytes
z.file().min(1).max(5 * 1024 * 1024).mime(["image/png"])

// JSON-representable values (v4) — validates the VALUE is JSON-serializable
// (recursive union of string | number | boolean | null | array | record)
z.json()

// Env-style boolean coercion: "true"/"yes"/"1" → true (v4)
z.stringbool({ truthy: ["true", "yes", "1"], falsy: ["false", "no", "0"] })
```

## Complex Types

### Objects

```typescript
const PersonSchema = z.object({
  name: z.string(),
  age: z.number(),
  address: z.object({
    street: z.string(),
    city: z.string(),
    country: z.string(),
  }),
});

type Person = z.infer<typeof PersonSchema>;

// Object methods
PersonSchema.shape                 // Access shape
PersonSchema.keyof()              // Get union of keys
PersonSchema.extend({ role: z.string() })  // Add fields
PersonSchema.safeExtend({ role: z.string() }) // Type-safe extend (inherits refinements)
PersonSchema.pick({ name: true }) // Pick specific fields
PersonSchema.omit({ age: true })  // Omit fields
PersonSchema.partial()            // Make all fields optional
PersonSchema.partial({ age: true }) // Make specific fields optional
PersonSchema.required()           // Make all fields required

// NOTE: .deepPartial() was REMOVED in v4 — build recursive partials manually
// (top-level z.deepPartial() landed post-4.4.3 and is not yet stable)

// Strict vs loose objects
z.strictObject({ ... })           // No extra keys allowed (throws)
z.object({ ... })                 // Strips extra keys (default)
z.looseObject({ ... })            // Allows extra keys
z.object({ ... }).catchall(z.number()) // Validate (and keep) unknown keys
```

### Arrays

```typescript
z.array(z.string())              // String array
z.array(z.number()).min(1)       // At least 1 element
z.array(z.number()).max(10)      // At most 10 elements
z.array(z.number()).length(5)    // Exactly 5 elements
z.array(z.number()).nonempty()   // At least 1 element

// Nested arrays
z.array(z.array(z.number()))     // number[][]
```

### Tuples

```typescript
z.tuple([z.string(), z.number()]) // [string, number]
z.tuple([z.string(), z.number()]).rest(z.boolean()) // [string, number, ...boolean[]]
```

### Enums and Literals

```typescript
// Enum
const RoleEnum = z.enum(["admin", "user", "guest"]);
type Role = z.infer<typeof RoleEnum>; // "admin" | "user" | "guest"

// Literal values
z.literal("exact_value")
z.literal(42)
z.literal(true)

// Native TypeScript enum
enum Fruits {
  Apple,
  Banana,
}
z.nativeEnum(Fruits)

// Enum methods
RoleEnum.enum.admin              // "admin"
RoleEnum.exclude(["guest"])      // Exclude values
RoleEnum.extract(["admin", "user"]) // Include only
```

### Unions

```typescript
// Basic union
z.union([z.string(), z.number()])

// Discriminated union (better performance & type inference)
const ResponseSchema = z.discriminatedUnion("status", [
  z.object({ status: z.literal("success"), data: z.any() }),
  z.object({ status: z.literal("error"), message: z.string() }),
]);

type Response = z.infer<typeof ResponseSchema>;
// { status: "success", data: any } | { status: "error", message: string }

// Exclusive union (v4): must match exactly ONE branch
z.xor([z.object({ a: z.string() }), z.object({ b: z.number() })])
```

### Intersections

```typescript
const BaseSchema = z.object({ id: z.string() });
const ExtendedSchema = z.object({ name: z.string() });

const Combined = z.intersection(BaseSchema, ExtendedSchema);
// Equivalent to: z.object({ id: z.string(), name: z.string() })
```

### Records and Maps

```typescript
// Record: object with typed keys and values (BOTH args required in v4)
z.record(z.string(), z.number())  // { [key: string]: number }
z.record(z.enum(["a", "b"]), z.string()) // Exhaustive: both keys REQUIRED

// Partial record (enum keys optional)
z.partialRecord(z.enum(["a", "b"]), z.string())

// Map
z.map(z.string(), z.number())    // Map<string, number>
z.set(z.string())                // Set<string>
```

## Advanced Patterns

**Load `references/advanced-patterns.md` for complete advanced validation and transformation patterns.**

### Quick Reference

**Refinements** (custom validation):
```typescript
z.string().refine((val) => val.length >= 8, "Too short");
z.object({ password, confirmPassword }).superRefine((data, ctx) => { /* ... */ });
```

**Transformations** (modify data):
```typescript
z.string().transform((val) => val.trim());
z.string().pipe(z.coerce.number());
z.preprocess((v) => (typeof v === "string" ? v.trim() : v), z.string()); // Transform BEFORE parsing
z.custom<string>((v) => typeof v === "string", { error: "Not a string" }); // Fully custom schema
```

**Multi-issue validation** (`.check()`, v4):
```typescript
z.string().check(z.minLength(3), z.startsWith("a")); // Compose check factories
z.string().check((payload) => {
  if (payload.value === "forbidden") {
    payload.issues.push({ code: "custom", message: "Not allowed", input: payload.value });
  }
});
```

**Template literals** (v4):
```typescript
const UserRole = z.templateLiteral(["role-", z.string()]); // "role-admin", "role-editor", ...
```

**Codecs** (bidirectional transforms - NEW in v4.1):
```typescript
const DateCodec = z.codec(
  z.iso.datetime(),
  z.date(),
  {
    decode: (str) => new Date(str),
    encode: (date) => date.toISOString(),
  }
);
```

**Recursive Types**:
```typescript
const CategorySchema: z.ZodType<Category> = z.lazy(() =>
  z.object({ name: z.string(), subcategories: z.array(CategorySchema) })
);
```

**Optional/Nullable**:
```typescript
z.string().optional()            // string | undefined
z.string().nullable()            // string | null
z.string().default("default")    // Provides default if undefined
```

**Readonly & Brand**:
```typescript
z.object({ ... }).readonly()     // Readonly properties
z.string().brand<"UserId">()     // Nominal typing
```

**→ Load `references/advanced-patterns.md` for:** Complete refinement patterns, async validation, codec examples, composable schemas, conditional validation, performance optimization

## Error Handling

**Load `references/error-handling.md` for complete error formatting and customization guide.**

### Quick Reference

**Error Formatting Methods**:
```typescript
// For forms
const { fieldErrors } = z.flattenError(error);

// For nested data
const tree = z.treeifyError(error);
const nameError = tree.properties?.user?.properties?.name?.errors?.[0];

// For debugging
console.log(z.prettifyError(error));
```

**Custom Error Messages** (three levels):
```typescript
// 1. Schema-level (highest priority)
z.string({ error: "Custom message" });
z.string().min(5, "Too short");

// 2. Per-parse level
schema.parse(data, { error: (issue) => "..." });

// 3. Global level
z.config({ customError: (issue) => "..." });
```

**Localization** (40+ languages):
```typescript
z.config(z.locales.es());  // Spanish
z.config(z.locales.fr());  // French
```

**→ Load `references/error-handling.md` for:** Complete error formatting examples, custom error patterns, localization setup, error code reference

## Type Inference

**Load `references/type-inference.md` for complete type inference and metadata documentation.**

### Quick Reference

**Basic Type Inference**:
```typescript
const UserSchema = z.object({ name: z.string() });
type User = z.infer<typeof UserSchema>; // { name: string }
```

**Input vs Output** (for transforms):
```typescript
const TransformSchema = z.string().transform((s) => s.length);
type Input = z.input<typeof TransformSchema>;   // string
type Output = z.output<typeof TransformSchema>; // number
```

**JSON Schema Conversion**:
```typescript
const jsonSchema = z.toJSONSchema(UserSchema, {
  target: "openapi-3.0",
  // .meta() data from the global registry is included by default
});
```

**Metadata**:
```typescript
// Add metadata
const EmailSchema = z.email().meta({
  title: "Email Address",
  description: "User's email address",
});

// Create custom registry
const formRegistry = z.registry<FormFieldMeta>();
```

**→ Load `references/type-inference.md` for:** Complete type inference patterns, JSON Schema options, metadata system, custom registries, brand types

## Functions

Validate function inputs and outputs with the v4 factory signature:

```typescript
const AddFunction = z.function({
  input: [z.number(), z.number()], // Arguments
  output: z.number(),              // Return type
});

// Implement typed function
const add = AddFunction.implement((a, b) => {
  return a + b; // Type-checked!
});

// Async functions
const FetchFunction = z.function({
  input: [z.string()],
  output: z.object({ data: z.any() }),
});

const fetchJson = FetchFunction.implementAsync(async (url) => {
  const response = await fetch(url);
  return response.json();
});
```

**Note**: the v3 chaining style (`z.function().args(...).returns(...)`) was removed in v4.

## Common Patterns

### Environment Variables

```typescript
const EnvSchema = z.object({
  NODE_ENV: z.enum(["development", "production", "test"]),
  DATABASE_URL: z.url(),
  PORT: z.coerce.number().int().positive().default(3000),
  API_KEY: z.string().min(32),
});

// Validate on startup
const env = EnvSchema.parse(process.env);

// Now use typed env
console.log(env.PORT); // number
```

### API Request Validation

```typescript
const CreateUserRequest = z.object({
  username: z.string().min(3).max(20),
  email: z.email(),
  password: z.string().min(8),
  age: z.number().int().positive().optional(),
});

// Express example
app.post("/users", async (req, res) => {
  const result = CreateUserRequest.safeParse(req.body);

  if (!result.success) {
    return res.status(400).json({
      errors: z.flattenError(result.error).fieldErrors,
    });
  }

  const user = await createUser(result.data);
  res.json(user);
});
```

### Form Validation

```typescript
const FormSchema = z.object({
  firstName: z.string().min(1, "First name required"),
  lastName: z.string().min(1, "Last name required"),
  email: z.email({ error: "Invalid email" }),
  age: z.coerce.number().int().min(18, "Must be 18+"),
  agreeToTerms: z.literal(true, {
    error: () => "Must accept terms",
  }),
});

type FormData = z.infer<typeof FormSchema>;
```

### Partial Updates

```typescript
const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.email(),
});

// For PATCH requests: make everything optional except id
const UpdateUserSchema = UserSchema.partial().required({ id: true });

type UpdateUser = z.infer<typeof UpdateUserSchema>;
// { id: string; name?: string; email?: string }
```

### Composable Schemas

```typescript
// Base schemas
const TimestampSchema = z.object({
  createdAt: z.date(),
  updatedAt: z.date(),
});

const AuthorSchema = z.object({
  authorId: z.string(),
  authorName: z.string(),
});

// Compose into larger schemas (.merge() is deprecated — use .extend with .shape)
const PostSchema = z.object({
  id: z.string(),
  title: z.string(),
  content: z.string(),
}).extend(TimestampSchema.shape).extend(AuthorSchema.shape);
```

## Ecosystem Integration

**Load `references/ecosystem-integrations.md` for complete framework and tooling integration guide.**

### Quick Reference

**ESLint Plugins**:
- `eslint-plugin-zod-x` - Enforces best practices
- `eslint-plugin-import-zod` - Enforces import style

**Framework Integrations**:
- **tRPC** - End-to-end typesafe APIs
- **React Hook Form** - Form validation (see `react-hook-form-zod` skill)
- **Prisma** - Generate Zod from database models
- **NestJS** - DTOs and validation pipes

**Code Generation**:
- **orval** - OpenAPI → Zod
- **Hey API** - OpenAPI to TypeScript + Zod
- **kubb** - API toolkit with codegen

**→ Load `references/ecosystem-integrations.md` for:** Setup instructions, integration examples, Hono middleware, Drizzle ORM patterns

## Troubleshooting

**Load `references/troubleshooting.md` for complete troubleshooting guide, performance tips, and best practices.**

### Quick Reference

**Common Issues**:
1. TypeScript strict mode required → Enable in `tsconfig.json`
2. Large bundle size → Use `z.lazy()` for code splitting
3. Slow async refinements → Cache or debounce
4. Circular dependencies → Use `z.lazy()`
5. Slow unions → Use `z.discriminatedUnion()`
6. Transform vs refine confusion → Use `.refine()` for validation, `.transform()` for modification

**Performance Tips**:
- Use `.discriminatedUnion()` (5-10x faster than `.union()`)
- Cache schema instances
- Use `.safeParse()` (avoids try-catch overhead)
- Lazy load large schemas

**Best Practices**:
- Define schemas at module level
- Use type inference (`z.infer`)
- Add custom error messages
- Validate at system boundaries
- Compose small schemas
- Document with `.meta()`

**→ Load `references/troubleshooting.md` for:** Detailed solutions, performance optimization, best practices, testing patterns

## Quick Reference

```typescript
// Primitives
z.string(), z.number(), z.boolean(), z.date(), z.bigint()

// Collections
z.array(), z.tuple(), z.object(), z.record(), z.map(), z.set()

// Special types
z.enum(), z.union(), z.discriminatedUnion(), z.intersection()
z.literal(), z.any(), z.unknown(), z.never()

// Modifiers
.optional(), .nullable(), .nullish(), .default(), .prefault()
.catch(), .readonly(), .brand(), .exactOptional()

// Validation
.min(), .max(), .length(), .regex()
.refine(), .superRefine(), .check(z.minLength(3))

// Top-level formats (v4)
z.email(), z.uuid(), z.url(), z.iso.datetime(), z.file(), z.json()

// Transformation
.transform(), .pipe(), .codec(), z.preprocess(), z.custom()

// Composition helpers
z.strictObject(), z.looseObject(), z.xor(), z.templateLiteral()

// Parsing
.parse(), .safeParse(), .parseAsync(), .safeParseAsync()

// Type inference
z.infer<typeof Schema>, z.input<typeof Schema>, z.output<typeof Schema>

// Error handling
z.flattenError(), z.treeifyError(), z.prettifyError()

// JSON Schema
z.toJSONSchema(schema, options)

// Metadata
.meta(), .describe()

// Object methods
.extend(), .safeExtend(), .pick(), .omit(), .partial(), .required()
.catchall(), .keyof()  // .merge() is deprecated — use .extend(other.shape)
```

## When to Load References

**Load `references/migration-guide.md` when:**
- Upgrading from Zod v3 to v4
- Questions about breaking changes
- Need migration checklist or rollback strategy
- Errors related to deprecated APIs (`.merge()`, `error.format()`, etc.)
- Number validation issues with `Infinity` or unsafe integers

**Load `references/error-handling.md` when:**
- Need to format errors for forms or UI
- Implementing custom error messages
- Questions about `z.flattenError()`, `z.treeifyError()`, or `z.prettifyError()`
- Setting up localization for error messages
- Need error code reference or pattern examples

**Load `references/advanced-patterns.md` when:**
- Implementing custom refinements or async validation
- Need bidirectional transformations (codecs)
- Working with recursive types or self-referential data
- Questions about `.refine()`, `.transform()`, or `.codec()`
- Need performance optimization patterns
- Implementing conditional validation

**Load `references/type-inference.md` when:**
- Questions about TypeScript type inference
- Need to generate JSON Schema for OpenAPI or AI
- Implementing metadata system for forms or documentation
- Need custom registries for type-safe metadata
- Questions about `z.infer`, `z.input`, `z.output`
- Using brand types for ID safety

**Load `references/ecosystem-integrations.md` when:**
- Integrating with tRPC, React Hook Form, Prisma, or NestJS
- Setting up ESLint plugins for best practices
- Generating Zod schemas from OpenAPI (orval, Hey API, kubb)
- Questions about Hono middleware or Drizzle ORM
- Need framework-specific integration examples

**Load `references/troubleshooting.md` when:**
- Encountering TypeScript strict mode errors
- Bundle size concerns or lazy loading needs
- Performance issues with large unions or async refinements
- Questions about circular dependencies
- Need best practices or testing patterns
- Confusion between `.refine()` and `.transform()`

**Load `references/best-practices.md` when:**
- Writing production Zod code or reviewing Zod usage
- Deciding strict vs loose objects, optional vs nullable, `any` vs `unknown`
- Optimizing hot paths (schema caching, avoiding dynamic schema creation, large arrays)
- Unsure where to validate (boundaries, `JSON.parse`, double validation)
- Want Incorrect/Correct examples with "when NOT to use" guidance

## Additional Resources

- **Official Docs**: https://zod.dev
- **GitHub**: https://github.com/colinhacks/zod
- **TypeScript Playground**: https://zod-playground.vercel.app
- **Zod Mini**: https://zod.dev/packages/mini
- **ESLint Plugin (Best Practices)**: https://github.com/JoshuaKGoldberg/eslint-plugin-zod-x
- **tRPC Integration**: https://trpc.io
- **Ecosystem**: https://zod.dev/ecosystem

---

**Production Notes**:
- Package version: 4.4.x (all APIs verified against [email protected])
- Zero dependencies
- Bundle size: ~5kb core / ~1.9kb zod/mini (gzipped)
- TypeScript 5.5+ required
- Strict mode required
- Last verified: 2026-08-20
- Skill version: 2.1.0 (fidelity audit + best-practices rules)

**What's New in 2.1.0**:
- 🔍 Fidelity audit: every documented API verified against [email protected] (typecheck + runtime tests)
- 📜 New `references/best-practices.md` rulebook (Incorrect/Correct/When-NOT format with impact ratings)
- ➕ New coverage: `zod/mini`, `.check()`, `catchall`, `z.preprocess`, `z.custom`, `z.templateLiteral`, `z.file`/`z.json`/`z.stringbool`/`z.xor`, `z.exactOptional`, `.safeExtend`, `z.fromJSONSchema`, expanded format validators
- 🐛 Fixed: install commands, `z.string().uuid()` → `z.uuid()`, v3 `.merge()`/`z.function()` chains, `.deepPartial()` (removed in v4), single-arg `z.record`, `toJSONSchema` `metadata` option

**What's New in 2.0.0**:
- ✨ Comprehensive v3 to v4 migration guide with breaking changes
- ✨ Enhanced error customization with three-level system
- ✨ Expanded metadata API with registry system
- ✨ Improved error formatting with practical examples
- ✨ Built-in localization support for 40+ locales
- ✨ Detailed codec documentation with real-world patterns
- ✨ Performance improvements and architectural changes explained

© secondsky · MIT · secondsky/claude-skills

Similar skills

All skills for Backend and APIs →

zod by other authors comes first.

zod PyModel A set of 46 validation and type inference rules for Zod 4 in TypeScript projects. Helps agents write schemas, handle errors, and clean up deprecated syntax. CX Codex +1 476installs zod Anivar Aravind A rule set for Zod v4: parsing untrusted data at boundaries, error handling, type inference, and the v3 migration. Useful when the agent writes schemas from memory and mixes up the API. CX Codex +1 1,000installs zod bobmatnyc A skill about the zod library: define a schema once and get runtime checks plus TypeScript types. Useful for forms and API payloads. CX Codex +1 887installs mcp-builder official anthropics This skill walks through building an MCP server in TypeScript or Python, from reading the protocol spec to writing tests and evaluation questions. 130,949installs claude-api official anthropics Reference skill for the Claude API and Anthropic SDK that enforces valid model IDs, adaptive thinking, and streaming. 74,198installs lark-im larksuite This skill lets an agent work with Lark IM messages, chats, files, and interactive cards. Use it when coding tasks need access to team conversations. CX Codex +1 472,900installs lark-event larksuite Listens to Lark/Feishu events and streams them as NDJSON. Use it for bots, message processing, and long-running subscribers. CX Codex +1 466,800installs caveman-discover JuliusBrussee Finds and labels every LLM workflow in your repository so Caveman Cloud breaks down spend by actual job rather than grouping everything into one bucket. CX Codex +1 104,400installs migration JuliusBrussee Enforces reversible, compatibility-safe transitions for schema, data, and API updates. Useful whenever data loss or rollout downtime is unacceptable. CX Codex +1 103,900installs

From the same set128

motion A skill that feeds your agent the Motion (Framer Motion) docs for React: drag-and-drop, scroll effects, layout transitions. Useful when the agent guesses at props. CX Codex +1 1,100installs playwright A Playwright skill for browser automation and end-to-end testing. It finds your running dev server and writes the test script for the task. CX Codex +1 1,000installs api-testing A skill that gets your agent writing HTTP API tests: Supertest for TypeScript, httpx and pytest for Python. Covers REST, GraphQL and error handling. CX Codex +1 890installs responsive-web-design Guides coding agents to write adaptive CSS with a mobile-first mindset. Covers responsive layouts, fluid clamp() typography, and media queries. CX Codex +1 684installs nano-banana-prompts Builds structured prompts for Gemini 2.5 Flash Image. Replaces keyword tags with descriptive prose for photography, art, and iterative image editing. CX Codex +1 600installs rest-api-design This skill hands your agent a set of REST conventions: resource names, HTTP methods, status codes and JSON response shape. Useful when you start a new API or want existing endpoints to match. CX Codex +1 586installs image-optimization Guides web image optimization using AVIF and WebP formats, responsive <picture> markup, and lazy loading strategies to cut page load times. CX Codex +1 585installs mobile-first-design Enforces mobile-first responsive styling starting at 320px, 48x48px touch targets, and a 500KB total page weight cap. CX Codex +1 568installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor