Zod logo

Zod

TypeScript-first 的 Schema 声明式校验库——以 TypeScript 类型推导为核心,在 tRPC 和 Next.js 生态中广泛使用。

精选工具表单校验Schema验证TypeScript-firsttRPC

Zod 是 TypeScript-first 的 Schema 校验库,定义一次 Schema 即可同时获得运行时校验和静态类型推导,v4 性能提升 14 倍,在 tRPC 和 Next.js 生态中不可替代,npm 周下载量超 1 亿次。

Zod

TypeScript-first 的 Schema 声明式校验库——以 TypeScript 类型推导为核心,在 tRPC 和 Next.js 生态中广泛使用。

技术简介说明

Zod 是由 Colin McDonnell 于 2020 年创建的 TypeScript-first Schema 声明与校验库。它的核心理念是「定义一次 Schema,同时获得运行时校验和静态类型推导」——开发者用 Zod 的链式 API 定义数据结构,TypeScript 编译器自动推导出对应的类型,运行时则通过 .parse() 方法对数据进行校验。这种「单一数据源」的设计消除了运行时校验与编译时类型之间的不一致问题,成为 TypeScript 生态中最受欢迎的数据校验方案。

Zod 在 tRPC 生态中扮演着不可替代的角色——tRPC 的输入校验完全依赖 Zod Schema,实现了从前端到后端的端到端类型安全。在 Next.js 生态中,Zod 同样被广泛用于 Server Actions 校验、API 路由校验和表单验证(配合 React Hook Form 的 zodResolver)。2025 年发布的 Zod v4 是一次里程碑式的重写,性能提升 14 倍,包体积缩小 57%,并引入了内置 JSON Schema 转换、@zod/mini 轻量变体等重要特性。

截至 2026 年,Zod 在 npm 上的周下载量超过 1 亿次,GitHub Stars 超过 43K,是 TypeScript 生态中使用最广泛的 Schema 校验库,深刻影响了 tRPC、Next.js、Fastify 等框架的数据校验实践。

基本信息

  • 官网:https://zod.dev
  • GitHub:https://github.com/colinhacks/zod
  • License:MIT
  • 最新版本:v4.4.0(2026 年)
  • 主要维护者/公司:Colin McDonnell
  • GitHub Stars:约 43,000+
  • npm 周下载量:约 1 亿+(截至 2026 年)
  • 贡献者:约 470+

快速上手

安装

# npm
npm install zod
 
# pnpm
pnpm add zod
 
# yarn
yarn add zod
 
# Deno(使用 npm 兼容层)
import { z } from "npm:zod"
 
# Bun
bun add zod

基础配置

Zod 是零配置库,安装后直接使用,无需额外配置文件。

import { z } from "zod"
 
// 如果使用 Zod v4 且想渐进迁移,可通过子路径导入
import { z as z4 } from "zod/v4"

最小示例

import { z } from "zod"
 
// 定义 Schema
const UserSchema = z.object({
  username: z.string().min(3).max(20),
  email: z.string().email(),
  age: z.number().int().min(0).max(150).optional(),
})
 
// 推导 TypeScript 类型
type User = z.infer<typeof UserSchema>
// { username: string; email: string; age?: number | undefined }
 
// 运行时校验
const result = UserSchema.safeParse({
  username: "john_doe",
  email: "[email protected]",
  age: 25,
})
 
if (result.success) {
  console.log(result.data) // 类型安全的数据
} else {
  console.log(result.error) // ZodError,包含详细的错误信息
}

核心概念与架构

Schema 即类型

Zod 最核心的设计是「Schema 即类型」——每个 Zod Schema 同时是:

  1. 运行时校验器:通过 .parse() / .safeParse() 在运行时校验数据
  2. TypeScript 类型生成器:通过 z.infer&lt;typeof Schema&gt; 推导出对应的 TypeScript 类型
const StringSchema = z.string()
type StringType = z.infer<typeof StringSchema> // string
 
const ObjectSchema = z.object({
  name: z.string(),
  tags: z.array(z.string()),
})
type ObjectType = z.infer<typeof ObjectSchema>
// { name: string; tags: string[] }

链式 API

Zod 的每个 Schema 类型都提供链式方法来添加约束:

z.string()
  .min(1, "不能为空")
  .max(100, "最多 100 个字符")
  .email("邮箱格式不正确")
  .optional()
  .nullable()
  .default("")

解析模式

Zod 提供三种解析模式:

  • .parse():校验成功返回数据,失败抛出 ZodError
  • .safeParse():返回 &#123; success: true, data &#125;&#123; success: false, error &#125;
  • .parseAsync() / .safeParseAsync():异步版本,支持异步 Schema(如 .refine() 返回 Promise)

错误处理

import { z } from "zod"
 
try {
  z.string().parse(123)
} catch (e) {
  if (e instanceof z.ZodError) {
    console.log(e.errors)
    // [{ code: "invalid_type", expected: "string", received: "number", path: [], message: "Expected string, received number" }]
  }
}

v4 架构改进

Zod v4 对内部架构进行了全面重写:

  • 共享核心包zod/v4/core 包含 Zod 和 @zod/mini 共享的核心逻辑
  • Tree-shakable 设计:v4 的模块结构更利于 Tree-shaking,未使用的 Schema 类型不会被打包
  • tsc 性能优化:减少了 TypeScript 编译器的类型推导负担,显著改善大型项目的 tsc 编译速度
  • 惰性绑定方法:减少内存使用,Schema 实例的方法不再在创建时绑定

核心特性

  • TypeScript 类型推导:从 Schema 自动推导出精确的 TypeScript 类型,消除运行时与编译时的不一致
  • 丰富的内置类型:string、number、boolean、date、bigint、symbol、undefined、null、void、any、unknown、never、array、tuple、object、union、intersection、enum、nativeEnum、literal、record、map、set、lazy、promise、effect 等
  • 链式约束 API.min().max().email().url().uuid().regex().includes().startsWith().endsWith() 等数十种约束方法
  • 自定义校验(refine / superRefine):支持跨字段校验、异步校验、复杂业务规则
  • Schema 转换(transform):在解析过程中对数据进行转换,如字符串转数字、格式化日期等
  • 默认值(default)与可选(optional / nullable / nullish):灵活处理缺失值
  • 管道(pipe):将多个 Schema 串联,前一级的输出作为后一级的输入
  • 内置 JSON Schema 转换(v4):通过 z.toJSONSchema() 原生生成 JSON Schema,用于 API 文档和 OpenAPI 规范
  • @zod/mini(v4):轻量变体,提供精简 API 和更小的包体积,适合对包大小敏感的场景
  • 全局元数据注册(v4):通过 z.globalRegistry 存储强类型元数据,与 JSON Schema 生成联动
  • 文件类型支持(v4):新增 z.file() 类型,支持文件类型、大小校验
  • 错误消息自定义:每个约束都支持自定义错误消息,支持国际化

生态图

核心生态

包名 / 工具说明
zod核心库(主入口 zod,v4 子路径 zod/v4
@zod/mini轻量变体,Tree-shakable API
zod/v4/coreZod 和 Mini 共享的核心包

表单集成

工具说明
react-hook-form + @hookform/resolvers/zodReact 表单方案,通过 zodResolver 集成
@vee-validate/zodVue 表单方案 VeeValidate 的 Zod 集成
@vee-validate/zod + FormKitFormKit 可与 Zod 结合使用
formsnapSvelte 表单库,深度集成 Zod

后端 / API 集成

工具说明
tRPC端到端类型安全 RPC 框架,输入校验完全基于 Zod
@hono/zod-openapiHono 框架的 OpenAPI 集成
fastify-type-provider-zodFastify 的 Zod 类型提供者
drizzle-zod从 Drizzle ORM Schema 自动生成 Zod Schema
prisma-zod / prisma-zod-generator从 Prisma Schema 生成 Zod Schema
zod-prisma-typesPrisma + Zod 类型生成

JSON Schema / OpenAPI

工具说明
zod(内置 v4)v4 内置 z.toJSONSchema() 方法
zod-to-json-schema第三方转换库(v4 内置后已不再积极维护)
zod-openapiZod Schema → OpenAPI 3.x 规范

验证扩展

工具说明
zod-validation-error将 ZodError 格式化为人类可读消息
@standard-schema/utils标准 Schema 接口工具
zod-i18n-mapZod 错误消息国际化

关键依赖关系

  • TypeScript 5.0+:Zod 依赖 TypeScript 的类型系统特性
  • tRPC:tRPC v10+ 将 Zod 作为默认(唯一推荐)输入校验库
  • Next.js:Next.js App Router + Server Actions 场景中,Zod 是事实上的标准校验方案

适用场景

  • tRPC 项目:tRPC 的输入校验完全依赖 Zod,使用 tRPC 即意味着使用 Zod
  • Next.js Server Actions:在 Server Actions 中校验客户端提交的数据,Zod 是最主流的选择
  • API 输入校验:Express / Fastify / Hono 等后端框架中校验请求体、查询参数、路由参数
  • 前后端共享类型:通过 z.infer 从 Schema 推导类型,在 Monorepo 中实现前后端类型共享
  • 表单校验:配合 React Hook Form、VeeValidate 等表单库,实现客户端表单校验
  • 配置文件校验:校验环境变量、配置文件、CLI 参数等结构化数据
  • 数据库 Schema 映射:通过 drizzle-zod、prisma-zod 等工具从数据库 Schema 自动生成 Zod Schema,实现类型安全的数据层
  • AI / LLM 输出校验:校验大语言模型返回的结构化数据(JSON),确保符合预期 Schema

开发与工程化

开发流程

# 克隆仓库
git clone https://github.com/colinhacks/zod.git
cd zod
 
# 安装依赖
pnpm install
 
# 运行测试
pnpm test
 
# 类型检查
pnpm typecheck
 
# 构建
pnpm build

自定义 Schema 扩展

import { z } from "zod"
 
// 扩展自定义方法
const phoneSchema = z.string().refine(
  (val) => /^1[3-9]\d{9}$/.test(val),
  { message: "请输入有效的手机号码" }
)
 
// 复用自定义 Schema
const contactSchema = z.object({
  name: z.string(),
  phone: phoneSchema,
  email: z.string().email(),
})

工程化最佳实践

  1. Schema 集中管理:将 Schema 定义集中在 schemas/validators/ 目录,便于复用和维护
  2. Schema 与路由/处理器分离:在 API 层,Schema 定义和路由处理逻辑分离,Schema 作为独立模块
  3. 错误消息统一:创建错误消息工厂函数,统一管理错误消息格式
  4. 环境变量校验:使用 Zod 校验 .env 文件,在应用启动时失败快速
// env.ts
import { z } from "zod"
 
const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  PORT: z.coerce.number().default(3000),
  NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
})
 
export const env = envSchema.parse(process.env)
// env.DATABASE_URL 类型为 string,env.PORT 类型为 number

CI/CD 集成

  • 类型检查pnpm typecheck 确保 Schema 定义和 z.infer 类型推导正确
  • 单元测试:对关键 Schema 编写测试,覆盖边界条件和错误路径
  • Contract Testing:在 Monorepo 中,用 Zod Schema 作为前后端契约,CI 中验证两端的一致性

性能与安全

性能特点(v4)

Zod v4 在性能方面进行了重大优化:

  • 字符串解析:比 v3 快约 14 倍
  • 数组解析:比 v3 快约 7 倍
  • 整体性能:约 3-6 倍的整体性能提升
  • 包体积:核心包缩小约 57%
  • tsc 编译:TypeScript 编译器性能显著改善,减少大型项目的类型检查时间
  • 内存使用:通过惰性绑定方法减少内存占用

⚠️ 注意:在某些特定场景(如 UI 密集型应用中的复杂嵌套 Schema)下,有社区报告指出 v4 可能比 v3 慢。建议根据实际项目做性能基准测试。

性能优化建议

  1. 使用 safeParse 而非 parse:避免异常捕获的开销
  2. 避免过度嵌套:深层嵌套的 object + union + tuple 会增加解析和类型推导成本
  3. 懒加载(lazy):对于大型递归 Schema,使用 z.lazy() 避免启动时的初始化开销
  4. 选择 @zod/mini:如果不需要完整的 Zod API,@zod/mini 提供更小的包体积
  5. 避免在热路径中使用 .refine():自定义 refine 函数无法被优化,对于简单约束优先使用内置方法

安全注意事项

  1. Zod 不能替代服务端验证:客户端 Zod 校验提升 UX,但服务端必须重新校验所有数据
  2. 输入消毒(Sanitization):Zod 校验数据结构但不自动消毒内容——需要额外的 z.string().transform() 或专用库处理 XSS
  3. 原型污染防护:Zod 的 z.object() 使用 Object.create(null) 创建解析结果,但自定义 .transform() 中需要注意
  4. 大输入限制:对于超大 JSON 输入,注意设置解析大小限制,避免 DoS 攻击
  5. 依赖安全:Zod 本身零依赖,但注意 zod-to-json-schema 等第三方包的安全更新

技术对比

特性Zod v4YupValibotJoiArkType
TypeScript 优先✅ 核心设计❌ 类型需额外处理✅ 类型推导❌ 需 @types✅ 类型推导
运行时校验
类型推导z.inferyup.InferTypeInferInputinfer<>
包体积中等(~57KB min+gzip)中等(~30KB)小(~8KB)大(~90KB)中等
零依赖
异步校验
JSON Schema✅ 内置(v4)
内置类型丰富度非常丰富中等丰富丰富丰富
链式 API✅ 管道式
错误消息自定义✅ 精细
社区生态最大(tRPC / Next.js)大(Formik 默认)增长中大(Express)增长中
性能快(v4 优化)中等
浏览器支持现代浏览器现代浏览器现代浏览器现代浏览器现代浏览器

选型建议

  • 选 Zod:使用 TypeScript、tRPC、Next.js,需要类型推导和运行时校验统一
  • 选 Yup:使用 Formik 的项目,Yup 是 Formik 的默认校验方案
  • 选 Valibot:对包大小极度敏感的项目,Valibot 的 Tree-shakable 设计使其可以只打包使用的模块
  • 选 Joi:使用 Express / Hapi 的项目,Joi 在这些生态中有深厚积累
  • 选 ArkType:追求极致类型推导精度,ArkType 的 TypeScript 类型系统利用更深入

最佳实践

1. 前后端共享 Schema(Monorepo)

// packages/shared/schemas/user.ts
import { z } from "zod"
 
export const createUserSchema = z.object({
  username: z.string().min(3).max(20),
  email: z.string().email(),
  role: z.enum(["admin", "user"]),
})
 
export type CreateUserInput = z.infer<typeof createUserSchema>
// apps/api/routes/users.ts
import { createUserSchema } from "@shared/schemas/user"
 
app.post("/users", (req, res) => {
  const result = createUserSchema.safeParse(req.body)
  if (!result.success) {
    return res.status(400).json({ errors: result.error.issues })
  }
  // result.data 类型安全
  const user = await db.user.create({ data: result.data })
  res.json(user)
})
// apps/web/components/CreateUserForm.tsx
import { createUserSchema } from "@shared/schemas/user"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
 
const form = useForm({
  resolver: zodResolver(createUserSchema),
})

2. 环境变量校验

// env.ts
import { z } from "zod"
 
const envSchema = z.object({
  NODE_ENV: z.enum(["development", "production", "test"]),
  DATABASE_URL: z.string().url(),
  REDIS_URL: z.string().url().optional(),
  JWT_SECRET: z.string().min(32),
  PORT: z.coerce.number().int().min(1).max(65535).default(3000),
  LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
})
 
export const env = envSchema.parse(process.env)

3. 错误消息格式化

import { z } from "zod"
import { fromZodError } from "zod-validation-error"
 
try {
  z.object({ name: z.string() }).parse({ name: 123 })
} catch (error) {
  if (error instanceof z.ZodError) {
    const validationError = fromZodError(error)
    console.log(validationError.message)
    // "Validation error: Expected string, received number at \"name\""
  }
}

4. Schema 组合与复用

// 基础 Schema
const baseSchema = z.object({
  id: z.string().uuid(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
})
 
// 扩展 Schema
const userSchema = baseSchema.extend({
  name: z.string(),
  email: z.string().email(),
})
 
// 部分 Schema(用于 PATCH)
const patchUserSchema = userSchema.partial().omit({ id: true, createdAt: true })
 
// Pick 特定字段
const userSummarySchema = userSchema.pick({ id: true, name: true })

5. 常见陷阱

  • 不要在 Schema 中使用 z.any()z.any() 破坏了类型安全,应该使用 z.unknown() 并进行后续校验
  • 不要忘记 .safeParse() 的错误处理:忽略 result.success === false 的情况会导致未校验的数据流入业务逻辑
  • 不要重复定义 Schema:对于复用频率高的数据结构,抽取为独立的 Schema 模块
  • 使用 z.coerce 处理字符串到数字/日期的转换z.coerce.number()z.string().transform(Number) 更简洁
  • 善用 .pipe() 进行数据转换链:将校验和转换分离,保持 Schema 的清晰性

技术局限与边界

已知限制

  1. TypeScript 编译开销:复杂的嵌套 Schema(深层 union + intersection + recursive)可能导致 tsc 编译时间显著增加。v4 已大幅优化,但极复杂的 Schema 仍需注意
  2. 包体积非最小:虽然 v4 缩小了 57%,但完整 Zod 仍约 57KB(min+gzip),对包大小极度敏感的场景应使用 @zod/mini 或 Valibot
  3. 不支持 JSON Schema → Zod:Zod 提供 Zod → JSON Schema 的转换,但反向转换(JSON Schema → Zod)需要第三方工具
  4. 运行时校验不等于类型守卫z.infer 推导的类型在运行时不存在,TypeScript 的类型系统无法在运行时强制执行
  5. v3 → v4 迁移成本:虽然支持渐进迁移(import &#123; z &#125; from "zod/v4"),但 .default() 行为变更、错误 API 统一等 Breaking Changes 需要仔细处理

不适用场景

  • 纯 JavaScript 项目:Zod 的核心价值在于 TypeScript 类型推导,纯 JS 项目无法利用这一特性(虽然运行时校验仍然有效),此时 Joi 或 Yup 可能更合适
  • 极致包大小要求:如果每个 KB 都很关键(如 CDN 加载的小脚本),考虑 Valibot 的 Tree-shakable 方案
  • 非结构化数据校验:Zod 擅长结构化数据(对象、数组)校验,对于纯文本内容校验(如 HTML 净化)需要额外工具
  • GraphQL Schema 定义:GraphQL 有自己的 Schema 定义方式,Zod 不适合直接定义 GraphQL 类型

迁移注意事项

  • v3 → v4 渐进迁移:通过 import &#123; z &#125; from "zod/v4" 可以在同一项目中混用 v3 和 v4,逐步迁移
  • Breaking Changes(v3 → v4)
    • .default() 与 optional 属性的交互行为变更
    • 统一错误 API(ZodError 结构有调整)
    • z.interface() 被移除(功能合并到 z.object()
    • 部分内部 API 变更
  • 社区 codemod 工具zod-v3-to-v4 可辅助自动迁移

学习资源

2026 年现状

最新版本

  • v4.4.0:最新稳定版本,持续优化 JSON Schema 生成和元数据处理
  • v4.0.0(2025 年 5 月):里程碑版本,性能提升 14 倍,包体积缩小 57%
  • v3.25.x:v3 的最终维护版本,与 v4 共存于同一个 npm 包中

发展趋势

  1. 性能持续优化:v4 之后仍在持续优化解析性能和 tsc 编译速度
  2. JSON Schema 生态中心:内置 JSON Schema 转换使 Zod 成为 API 文档和 OpenAPI 规范的核心工具
  3. AI 时代的数据校验:Zod 在 LLM 输出校验(Structured Output)场景中越来越重要,成为 AI 应用中校验模型输出事实标准
  4. 标准化推动:Zod 推动了 JavaScript Schema 校验接口的标准化讨论(Standard Schema)

社区活跃度

  • GitHub Stars:约 43,000+
  • npm 周下载量:约 1 亿+(截至 2026 年,是 npm 上下载量最大的校验库之一)
  • GitHub Issues / Discussions 高度活跃
  • 贡献者约 470+,生态扩展包持续增长
  • 在 tRPC、Next.js、Fastify、Hono 等主流框架中作为默认或推荐的校验方案

未来路线图

  • JSON Schema 生成的持续完善(更多 Schema 类型支持、更好的元数据映射)
  • @zod/mini 的 API 完善和功能对齐
  • Standard Schema 规范的推进和生态采纳
  • 性能基准的持续监控和优化
  • 更丰富的第三方集成(更多 ORM、API 框架、表单库)