Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
bjornmelin avatar

Zod V4

  • 13 installs
  • 5 repo stars
  • Updated August 5, 2026
  • bjornmelin/dev-skills

Zod v4 is a Claude Code skill giving expert guidance for Zod v4 schema validation in TypeScript, including migration from Zod 3 and JSON Schema/OpenAPI generation.

About

Zod v4 provides guidance for schema validation in TypeScript using Zod v4. It covers designing schemas, migrating from Zod 3, handling validation errors, and generating JSON Schema or OpenAPI. A developer uses it when defining data contracts or integrating validation with React Hook Form, tRPC, Hono, or Next.js. It documents v4 APIs such as top-level string formats, strictObject/looseObject, registries, branded types, and recursive schemas.

  • Expert guidance for Zod v4 schema design and migration from Zod 3
  • Covers top-level string formats, strictObject/looseObject, branded and recursive schemas, and codecs/transforms
  • Integrates with React Hook Form, tRPC, Hono, and Next.js and generates JSON Schema/OpenAPI

Zod V4 by the numbers

  • 13 all-time installs (skills.sh)
  • Ranked #3,516 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

zod-v4 capabilities & compatibility

Capabilities
schema validation · type inference · json schema generation · error handling
Use cases
api development · refactoring
IDEs
vscode · cursor ide
From the docs

What zod-v4 says it does

v4 moved string validators to top-level functions:
SKILL.md
z.object({}) // Allows unknown keys (default)
SKILL.md
// Generate JSON Schema
SKILL.md
npx skills add https://github.com/bjornmelin/dev-skills --skill zod-v4

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs13
repo stars5
Last updatedAugust 5, 2026
Repositorybjornmelin/dev-skills

What it does

Design and migrate Zod v4 schemas in TypeScript, handle validation errors, and generate JSON Schema/OpenAPI.

Who is it for?

Designing and migrating Zod v4 validation schemas and error handling in TypeScript apps.

Skip if: Non-TypeScript validation or runtimes without Zod.

When should I use this skill?

Designing schemas, migrating from Zod 3, handling validation errors, generating JSON Schema/OpenAPI, or integrating with RHF/tRPC/Hono/Next.js.

What you get

Correct, idiomatic Zod v4 schemas with proper error handling and generated JSON Schema/OpenAPI.

  • Zod v4 schemas
  • validation error handling
  • JSON Schema/OpenAPI output

By the numbers

  • 4 bundled reference guides
  • 10-plus row v3-to-v4 migration table

Files

SKILL.mdMarkdownGitHub ↗

Zod v4 Schema Validation

Quick Start

pnpm add zod@^4.3.5
import { z } from 'zod';

// Define schema
const User = z.object({
  name: z.string().min(1),
  email: z.email(),
  age: z.number().positive(),
});

// Parse (throws on error)
const user = User.parse({ name: "Alice", email: "alice@example.com", age: 30 });

// Safe parse (returns result)
const result = User.safeParse(data);
if (result.success) {
  result.data; // validated
} else {
  console.log(z.prettifyError(result.error));
}

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

Versioning + Imports (v4.3.5)

  • Use import { z } from "zod" for v4 (package root now exports v4).
  • Use import * as z from "zod/mini" for Zod Mini.
  • Use import * as z from "zod/v3" only if you must stay on v3.

Workflow: Determine Task Type

Designing new schemas? → Read API Reference

Migrating from Zod 3? → Read Migration Guide

Working with codecs, errors, JSON Schema, or metadata? → Read Advanced Features

Integrating with frameworks (RHF, tRPC, Hono, Next.js)? → Read Ecosystem Patterns

---

Key v4 Concepts

Top-Level String Formats

v4 moved string validators to top-level functions:

// v4 style (preferred)
z.email()
z.uuid()
z.url()
z.ipv4()
z.ipv6()
z.iso.date()
z.iso.datetime()

// v3 style (deprecated but works)
z.string().email()

Object Variants

z.object({})        // Allows unknown keys (default)
z.strictObject({})  // Rejects unknown keys
z.looseObject({})   // Explicitly allows unknown keys

Unified Error Parameter

// String message
z.string().min(5, { error: "Too short" });

// Function for dynamic messages
z.string({
  error: (iss) => iss.input === undefined ? "Required" : "Invalid"
});

Type Inference

const Schema = z.object({ name: z.string() });
type Schema = z.infer<typeof Schema>;

// For transforms, get input/output separately
const Transformed = z.string().transform(s => s.length);
type Input = z.input<typeof Transformed>;   // string
type Output = z.output<typeof Transformed>; // number

---

Common Patterns

Discriminated Unions

const Event = z.discriminatedUnion("type", [
  z.object({ type: z.literal("click"), x: z.number(), y: z.number() }),
  z.object({ type: z.literal("keypress"), key: z.string() }),
]);

Exhaustive Records

const Status = z.enum(["pending", "active", "done"]);

// All keys required
z.record(Status, z.number())  // { pending: number; active: number; done: number }

// Keys optional
z.partialRecord(Status, z.number())  // { pending?: number; active?: number; done?: number }

Recursive Schemas

const Category = z.object({
  name: z.string(),
  get subcategories() { return z.array(Category) }
});

Branded Types

const UserId = z.string().brand<"UserId">();
const PostId = z.string().brand<"PostId">();

type UserId = z.infer<typeof UserId>;
// Cannot assign UserId to PostId

Transforms and Pipes

// Transform
z.string().transform(s => s.toUpperCase())

// Pipe (chain schemas)
z.pipe(
  z.string(),
  z.coerce.number(),
  z.number().positive()
)

Default Values

// Output default (v4)
z.string().default("guest")

// Input default (pre-transform)
z.string().transform(s => s.toUpperCase()).prefault("hello")
// Missing => "HELLO"

---

Error Handling

Pretty Print

const result = schema.safeParse(data);
if (!result.success) {
  console.log(z.prettifyError(result.error));
  // ✖ Invalid email
  //   → at email
}

Flat Structure (Forms)

const flat = z.flattenError(result.error);
// { formErrors: [], fieldErrors: { email: ["Invalid email"] } }

Tree Structure (Nested)

const tree = z.treeifyError(result.error);
// { properties: { email: { errors: ["Invalid email"] } } }

---

JSON Schema / OpenAPI

const schema = z.object({
  name: z.string(),
  email: z.email(),
}).meta({ id: "User", title: "User" });

// Generate JSON Schema
const jsonSchema = z.toJSONSchema(schema);

// For OpenAPI 3.0
z.toJSONSchema(schema, { target: "openapi-3.0" });

// Using registry for multiple schemas
z.globalRegistry.add(schema, schema.meta());
const allSchemas = z.toJSONSchema(z.globalRegistry);

---

v3 to v4 Migration Quick Reference

v3v4
z.string().email()z.email()
z.nativeEnum(MyEnum)z.enum(MyEnum)
{ message: "..." }{ error: "..." }
.strict()z.strictObject({})
.passthrough()z.looseObject({})
.merge(other).extend(other.shape)
z.record(valueSchema)z.record(z.string(), valueSchema)
.deepPartial()Nest .partial() manually
error.format()z.treeifyError(error)
error.flatten()z.flattenError(error)

Breaking Changes

  • Numbers: No Infinity, stricter .safe() and .int()
  • UUID: RFC 4122 compliant (use z.guid() for permissive)
  • Defaults in optional: z.string().default("x").optional() now applies default
  • z.unknown(): No longer implicitly optional
  • Error precedence: Schema-level wins over global

Run codemod: npx zod-v3-to-v4

---

Framework Integration Quick Start

React Hook Form

import { zodResolver } from '@hookform/resolvers/zod';

const { register, handleSubmit, formState: { errors } } = useForm({
  resolver: zodResolver(schema),
});

tRPC

publicProcedure
  .input(z.object({ id: z.string() }))
  .query(({ input }) => getById(input.id))

Hono

import { zValidator } from '@hono/zod-validator';

app.post('/users', zValidator('json', schema), (c) => {
  const data = c.req.valid('json');
});

Next.js Server Actions

'use server';

const result = schema.safeParse(Object.fromEntries(formData));
if (!result.success) {
  return { errors: z.flattenError(result.error).fieldErrors };
}

---

Reference Files

  • API Reference - All schema types, methods, and validation APIs
  • Advanced Features - Codecs, error handling, metadata, JSON Schema
  • Migration Guide - Complete v3 to v4 migration reference
  • Ecosystem Patterns - Framework integrations and organization patterns

Related skills

FAQ

How do string formats change in v4?

v4 moved string validators to top-level functions such as z.email(), z.uuid(), and z.url(), replacing z.string().email().

How do you generate JSON Schema?

Use z.toJSONSchema(schema), and target 'openapi-3.0' for OpenAPI 3.0 output.

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.