Yup
一个简洁、声明式的 JavaScript/TypeScript 对象 Schema 校验库,与 Formik 深度集成,是 React 表单校验生态中最经典的校验方案。
Yup 是声明式 Schema 校验库,以链式 API 和 Formik 深度集成著称,拥有 23,700+ Stars 和约 1200 万周下载量,是 React 表单校验生态中最经典的方案。
Yup
一个简洁、声明式的 JavaScript/TypeScript 对象 Schema 校验库,与 Formik 深度集成,是 React 表单校验生态中最经典的校验方案。
技术简介说明
Yup 是一个用于运行时值解析与校验的 JavaScript Schema 构建库。它提供了一套流式(fluent)、链式、声明式的 API,允许开发者用直观的方式定义数据形状(Schema),并据此对任意输入值进行转换(cast)、校验(validate)和类型推断(describe)。Yup 的设计哲学深受 Joi 启发,但专注于浏览器端与对象校验场景,API 更轻量、更易扩展。
自 2014 年首次发布以来,Yup 凭借与 Formik 的天然集成,成为 React 表单领域的事实标准。它提供了完善的异步校验支持、内置类型转换、条件 Schema、自定义错误消息等能力,极大简化了复杂表单场景下的数据校验逻辑。
进入 2025–2026 年,虽然 Zod、Valibot 等新一代库凭借更优秀的 TypeScript 类型推断和更小的包体积获得了大量新项目的青睐,但 Yup 仍凭借 ~1200 万 npm 周下载量和庞大的存量项目生态,保持着 Schema 校验领域的重要地位。对于已有 Formik + Yup 技术栈的项目,Yup 依然是最成熟、最稳定的选择。
基本信息
- 官网:https://github.com/jquense/yup(无独立官网,以 GitHub README 为主文档)
- GitHub:https://github.com/jquense/yup
- License:MIT
- 最新版本:1.7.1(2025-09-21 发布)
- 主要维护者:Jason Quense(jquense),React Big Calendar、react-widgets 等库的作者
- GitHub Stars:~23,700(2026 年)
- npm 周下载量:~1,200 万(2026 年,Snyk / PkgPulse 数据)
- 首次发布:2014 年 9 月
- 语言:TypeScript(自 v0.32 起内置类型)
- 运行环境:浏览器 + Node.js
快速上手
安装
# npm
npm install yup
# yarn
yarn add yup
# pnpm
pnpm add yup
# bun
bun add yup注意:Yup v1.0+ 要求 Node.js >= 14,且不再提供 CommonJS 和 ESM 双包的旧格式,现代打包工具均可正常使用。
基础配置
Yup 是零配置的库——安装后即可直接使用,无需初始化或注册插件。
import * as yup from 'yup'如果需要自定义默认错误消息,可以在应用入口调用 setLocale:
import { setLocale } from 'yup'
setLocale({
mixed: {
required: '${path} 是必填字段',
notType: '${path} 类型不匹配',
},
string: {
min: '${path} 至少 ${min} 个字符',
max: '${path} 最多 ${max} 个字符',
email: '${path} 不是合法的邮箱格式',
},
})最小示例
import * as yup from 'yup'
// 定义 Schema
const schema = yup.object({
name: yup.string().required('请输入姓名').min(2, '姓名至少 2 个字符'),
age: yup.number().required('请输入年龄').integer('必须为整数').min(0).max(150),
email: yup.string().required('请输入邮箱').email('邮箱格式不正确'),
})
// 同步校验
try {
const result = schema.validateSync({
name: 'Alice',
age: 25,
email: '[email protected]',
})
console.log(result) // { name: 'Alice', age: 25, email: '[email protected]' }
} catch (err) {
if (err instanceof yup.ValidationError) {
console.log(err.errors) // 错误信息数组
}
}
// 异步校验
schema
.isValid({ name: '', age: -1, email: 'bad' })
.then((valid) => console.log(valid)) // false核心概念与架构
核心概念
- Schema(模式):Yup 的核心抽象。每个数据类型(
string、number、boolean、date、array、object、mixed)都是一个 Schema 工厂,返回可链式调用的 Schema 实例。 - Validation(校验):通过
validate()/validateSync()对输入值执行规则检查,失败时抛出ValidationError。 - Casting(类型转换):
cast()方法在运行校验前,先将输入值转换为 Schema 声明的目标类型(如字符串'25'→ 数字25)。 - Transform(自定义转换):通过
.transform()插入自定义的类型转换逻辑,在 cast 阶段执行。 - Test(自定义规则):通过
.test()添加完全自定义的校验逻辑,可访问 Schema 上下文(父对象、兄弟字段等)。 - When / Condition(条件 Schema):根据其他字段的值动态调整校验规则。
- reach(路径寻址):
yup.reach(schema, 'path.to.field')可精确访问嵌套 Schema,便于动态修改规则。
架构设计
┌─────────────────────────────────────────────────┐
│ 用户代码层 │
│ yup.object({...}).validate(data) │
└─────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Schema 树(不可变结构) │
│ ObjectSchema → FieldSchema[] (每字段带规则链) │
└─────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ 校验执行引擎(同步/异步) │
│ 1. cast(类型转换) │
│ 2. transform(自定义转换) │
│ 3. 内置规则检查(required/min/max/type...) │
│ 4. 自定义 test 执行 │
│ 5. ValidationError 聚合 │
└─────────────────────────────────────────────────┘
Yup 的 Schema 对象是不可变的——每次链式调用都返回一个新的 Schema 实例,原有 Schema 不会被修改。这种设计让 Schema 可以安全地组合、复用和共享。
核心特性
- 声明式链式 API:通过
.string().required().min(3)风格流式定义校验规则,可读性强、上手快。 - 完善的内置类型:
string、number、boolean、date、array、object、mixed、lazy、ref,覆盖绝大多数业务场景。 - 异步校验支持:
validate()返回 Promise,内置对异步test(如远程接口查重)的原生支持,无需额外封装。 - 类型转换(Casting):自动将表单字符串值转换为数字、日期等目标类型,避免手动
parseInt/new Date。 - 条件 Schema(when):根据兄弟字段或上下文值动态改变规则(如
country === 'CN'时要求身份证号)。 - 嵌套与递归 Schema:通过
yup.lazy()支持循环引用和递归数据结构(如树形节点)。 - 自定义错误消息:支持插值
${path}、${value}、${min}等变量,可全局配置默认消息(setLocale)。 - TypeScript 类型推断:通过
yup.InferType<typeof schema>从 Schema 自动推断 TypeScript 类型,减少重复定义。 - Formik 深度集成:Formik 官方推荐的校验方案,
validationSchema直接接受 Yup Schema,自动适配validate接口。 - 可扩展性:通过
addMethod()为任意内置类型添加自定义链式方法(如yup.string().phone())。
生态图
核心依赖与集成
┌─────────────────────────────────────────────────┐
│ 表单框架集成 │
│ Formik(官方) | React Hook Form | VeeValidate │
│ MobX React Form | Redux Form(已停止维护) │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ 社区扩展插件 │
│ yup-phone — 手机号校验 │
│ yup-locale-* — 多语言错误消息(cs/de/fr/ja…) │
│ yup-locales — 综合多语言包 │
│ @vee-validate/yup — VeeValidate 适配器 │
│ yup-interval — 时间区间校验 │
│ react-formgen — Schema → React 表单自动生成 │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ 类型推断工具 │
│ yup.InferType<typeof schema> │
│ @types/yup(v0.32 前需要,v1+ 已内置) │
└─────────────────────────────────────────────────┘
关键社区项目
| 项目 | 用途 |
|---|---|
@vee-validate/yup | Vue VeeValidate 与 Yup 的官方适配层 |
yup-phone | 国际手机号格式校验 |
yup-locales / yup-locale-* | 多语言错误消息包 |
mobx-react-form + yup 插件 | MobX 表单库的 Yup 集成 |
yup-schema-generator | 从 JSON Schema 生成 Yup Schema |
react-formgen | 从 Schema 自动生成 React 表单组件 |
适用场景
- React + Formik 表单应用(最佳场景):Yup 是 Formik 的官方推荐校验方案,
validationSchema一行配置即可接入,适合中后台管理系统、CMS、CRUD 应用。 - 已有 Formik + Yup 技术栈的项目维护与扩展:Yup 存量用户庞大(~1200 万/周下载),大量生产系统依赖它,维护场景下无需迁移。
- 需要异步校验的表单:如用户名查重、邮箱是否已注册等场景,Yup 原生支持异步
test,可直接返回 Promise。 - 纯 JavaScript 项目(无 TypeScript 强需求):Yup 的 API 设计最早面向 JS,在 JS 项目中体验流畅;TS 支持虽已完善但类型推断能力相比 Zod / Valibot 略逊。
- 服务端对象校验(Node.js API 层):可用于 Express / Koa 等框架中对请求体进行基础校验,但在高吞吐 API 场景下性能不及 Zod / Valibot。
- 需要表单值自动类型转换的场景:Yup 的
cast()可将表单字符串自动转为数字/日期/布尔,省去大量手动转换逻辑。 - 复杂条件校验:如多步表单中根据上一步选择动态调整规则,
when()和yup.lazy()提供了强大的声明式条件能力。
开发与工程化
开发流程
- Schema 定义阶段:将业务数据模型翻译为 Yup Schema,每个字段对应一条链式规则。
- 单元测试:对关键 Schema 编写
.isValid()/.validateSync()测试,覆盖正常与异常边界。 - 表单集成:将 Schema 传入 Formik
validationSchema或 React Hook Form 的resolver。 - 错误消息国际化:使用
setLocale()配合i18next等框架注入多语言消息。 - CI 校验:在 CI 中运行
yup相关单测,确保 Schema 变更不会引入回归。
构建部署
Yup 是纯前端库,构建工具无关。在 Next.js、Vite、Webpack、Rollup 等现代打包工具中均可直接使用,支持 ESM 和 CJS 双格式。
// vite.config.ts — 无需特殊配置,Yup 自动被打包
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})CI/CD 集成
# GitHub Actions 示例
- name: Run tests
run: pnpm test -- --testPathPattern=yup
- name: Type check
run: pnpm typecheck最佳工程实践
- Schema 与 UI 分离:将 Schema 定义放在独立的
schemas/或validation/目录,便于复用和测试。 - Schema 组合复用:用
yup.object().shape()+concat()或yup.object().concat(baseSchema)复用基础 Schema。 - 错误消息统一:全局
setLocale()一次配置,避免在每处 Schema 重复写中文消息。
性能与安全
性能特点
- 包体积:~18–30 KB(gzip 后),在 Schema 校验库中偏大。相比之下 Valibot 可做到 < 2 KB,Zod 约 12–15 KB。
- 校验速度:Yup 的设计偏向易用性和功能完整性,在复杂 Schema 的校验速度上不及 Zod(Zod 约 2x 快于 Yup)和 Valibot(Valibot 约 2–3x 快于 Yup)。
- 冷启动:首次导入时加载完整库代码,无 tree-shaking 支持(所有类型都会被打包),在 bundle size 敏感的场景下是瓶颈。
优化建议
- 动态
import():对于仅在特定路由使用的复杂 Schema,使用const schema = await import('./schema').then(m => m.schema)延迟加载。 - 避免重复定义:复用 Schema 实例,不要在组件内每次渲染重新创建 Schema。
validateSync优先:在不需要异步规则时,validateSync()比validate()更快(省去 Promise 开销)。
安全注意事项
- Yup 不防注入:Yup 只做格式校验,不处理 SQL 注入、XSS 等安全问题。服务端校验后仍需配合参数化查询和输出转义。
- cast 的边界:
cast()的类型转换可能对恶意输入产生意外结果(如超大数字字符串),对敏感字段应额外限制范围。 - 依赖审计:Yup 本身无已知严重安全漏洞,但应定期
npm audit检查间接依赖。 - 服务端二次校验:客户端 Yup 校验仅作为 UX 层,API 层必须使用独立的校验逻辑(不信任任何客户端输入)。
已知性能瓶颈
- 大型数组 Schema(如
yup.array().of(yup.object({...})).min(1000))在元素过多时性能下降明显。 - 深度嵌套对象(> 5 层)的
describe()和validate()有额外开销。 - 没有 tree-shaking,即使只用了
yup.string(),也会打包整个库。
技术对比
| 维度 | Yup | Zod | Valibot |
|---|---|---|---|
| 包体积 | ~18–30 KB | ~12–15 KB | < 2 KB(tree-shakeable) |
| 校验速度 | 中等 | 快(V8 优化好) | 快(复杂 Schema 最优) |
| TypeScript 推断 | 良好(InferType) | 优秀(精确推断) | 优秀(精确推断) |
| Tree-shaking | ❌ 不支持 | ❌ 不支持 | ✅ 完整支持 |
| 异步校验 | ✅ 原生支持 | ✅ 原生支持 | ✅ 原生支持 |
| 类型转换 | ✅ 内置 cast | ❌ 需手动 | ❌ 需 pipeline |
| 条件 Schema | ✅ when() 强大 | ✅ refine / superRefine | ✅ if pipeline |
| Formik 集成 | ✅ 官方支持 | ⚠️ 需手动适配 | ⚠️ 需手动适配 |
| React Hook Form | ✅ 通过 resolver | ✅ 官方 resolver | ✅ 官方 resolver |
| 社区生态 | 成熟(23.7k stars) | 最活跃(~80k stars) | 快速增长(~8.4k stars) |
| 学习曲线 | 低 | 低 | 中(需理解 pipeline) |
| API 风格 | 链式(fluent) | 链式(fluent) | Pipeline 函数式 |
| Schema 序列化 | ❌ 困难 | ⚠️ 有限 | ✅ 支持(valibot-serialize) |
选型建议
- 选 Yup:项目已使用 Formik;需要表单值自动 cast;维护现有 Formik + Yup 代码库。
- 选 Zod:需要最强 TypeScript 类型推断;团队偏好链式 API;项目以 TS 为主。
- 选 Valibot:对包体积极度敏感;需要 tree-shaking;新项目且无历史包袱。
最佳实践
生产环境建议
1. Schema 独立管理
// schemas/user.ts
import * as yup from 'yup'
export const userSchema = yup.object({
name: yup.string().required(),
email: yup.string().email().required(),
})
export type User = yup.InferType<typeof userSchema>2. 复用基础 Schema
const baseSchema = yup.object({
createdAt: yup.date().default(() => new Date()),
updatedAt: yup.date().default(() => new Date()),
})
const userSchema = baseSchema.shape({
name: yup.string().required(),
email: yup.string().email().required(),
})
const postSchema = baseSchema.shape({
title: yup.string().required(),
content: yup.string().required(),
})3. 全局错误消息配置
// i18n/yup.ts
import { setLocale } from 'yup'
setLocale({
mixed: {
required: '${path} 不能为空',
notType: '${path} 类型不正确',
},
string: {
email: '请输入有效的邮箱地址',
min: '${path} 至少需要 ${min} 个字符',
max: '${path} 最多 ${max} 个字符',
url: '请输入有效的 URL',
},
number: {
min: '${path} 不能小于 ${min}',
max: '${path} 不能大于 ${max}',
integer: '${path} 必须为整数',
},
})4. 自定义链式方法
// 为 string 类型添加 phone 方法
yup.addMethod(yup.string, 'phone', function (message = '请输入有效的手机号') {
return this.matches(/^1[3-9]\d{9}$/, {
message,
excludeEmptyString: true,
})
})
// 使用
const schema = yup.object({
mobile: yup.string().phone(),
})5. 异步校验防抖
const emailSchema = yup
.string()
.email()
.test('unique', '该邮箱已被注册', async (value) => {
if (!value) return true
const res = await fetch(`/api/check-email?email=${value}`)
const data = await res.json()
return !data.exists
})常见陷阱
validatevsvalidateSync:validate是异步的,返回 Promise;在同步代码中误用会拿到 Promise 对象而非数据。cast静默失败:cast()对无法转换的值默认返回原值,而非抛出异常。需要严格转换时使用cast(value, { strict: true })。when的is条件:is字段可以是值、函数或 Schema,混用容易出错,建议统一使用函数形式。- Schema 实例共享:Yup Schema 是不可变的,可以在多个表单间安全复用——但不要在其上误用
concat()并期望原实例改变。 - 数组元素校验:
yup.array().of(schema)中,空数组[]默认是合法的,如需必填数组要显式加.required().min(1)。 - TypeScript 类型同步:
yup.InferType推断的类型在复杂条件 Schema(when)下可能不准确,关键场景建议手动定义类型。
技术局限与边界
已知限制
- 无 Tree-shaking:Yup 的模块结构不支持 tree-shaking,即使只使用
yup.string(),整个库(~18–30 KB)都会被打包。在包体积极度敏感的场景(边缘函数、嵌入式 widget)下是明显劣势。 - TypeScript 类型推断有限:
InferType在条件 Schema(when)、lazy()和复杂嵌套场景下无法精确推断,通常需要手动补全类型。 - API 设计偏老:Yup 的链式 API 设计于 TypeScript 全面普及之前,部分高级类型场景下类型推断不如 Zod / Valibot 流畅。
- 无 Schema 序列化:Yup Schema 无法序列化到 JSON,不能在服务端与客户端之间传递 Schema 定义,也不支持从 Schema 生成 JSON Schema。
- 社区活跃度下降:2024–2026 年,Yup 的新增 star 速度明显放缓(每月仅个位数),新特性和重大修复较少,进入维护模式。
- 新项目采用率下降:2025–2026 年的新项目(尤其 TS-first 项目)更倾向于选择 Zod 或 Valibot,Yup 在新项目中的占比持续下降。
不适用场景
- 包体积极度敏感场景:如边缘函数(Cloudflare Workers)、嵌入式 JS widget、移动端 H5 性能要求极高场景,Valibot 是更优选择。
- 纯 TypeScript 新项目(无 Formik):Zod 在 TS 类型推断和社区活跃度上全面领先,新项目首选 Zod。
- 需要 Schema 序列化/跨端传递:如 tRPC、前后端共享 Schema 场景,Yup 无法满足。
- 高吞吐 API 校验:如每秒处理数千次校验的后端服务,Yup 的性能不及 Zod 和 Valibot。
迁移注意事项
- 从 Yup 迁移到 Zod:API 风格相似(都是链式),迁移成本中等。注意
cast()在 Zod 中不存在,需手动处理类型转换;when()需要改写为refine/superRefine。 - 从 Yup 迁移到 Valibot:API 风格差异较大(链式 vs pipeline),需要全面改写。但 Valibot 的 pipe 模型语义更清晰,迁移后代码可维护性更高。
- 不建议为迁移而迁移:对于已稳定运行的 Formik + Yup 项目,在没有明确痛点(如包体积、性能)的情况下,迁移 ROI 不高。
学习资源
官方文档
教程
- Yup Validation Guide(UptimeRobot) — 全面的 Yup 使用指南
- How to use Yup Validation with React Hook Form(Strapi) — 与 React Hook Form 集成实战
- Form Validation in React with Yup(Formspree) — React 表单校验入门
- How to use Yup for validation in Node.js(CoreUI) — 服务端使用指南
- Yup validate forms in React(Contentful) — Contentful 团队的实践经验
社区资源
- GitHub Issues — Bug 报告与功能讨论
- Stack Overflow
yuptag — 问答社区 - Yup vs Zod vs Joi 对比(LogRocket Blog) — 技术对比文章
2026 年现状
最新版本
- 当前稳定版:
1.7.1(2025-09-21 发布) - 发布节奏:2025 年发布了
1.7.0和1.7.1,以补丁和小特性为主,无重大架构变更。
发展趋势
- 维护模式:Yup 已进入成熟维护阶段,新功能开发基本停滞,以 bug 修复和依赖更新为主。
- 下载量稳定但增长停滞:~1200 万周下载量主要来自存量项目,新项目采用率被 Zod 和 Valibot 持续蚕食。
- 社区讨论热度下降:GitHub Issues 的新增讨论频率较 2022–2023 年高峰期明显减少。
社区活跃度
| 指标 | 数值(2026 年) |
|---|---|
| GitHub Stars | ~23,700 |
| npm 周下载量 | ~1,200 万 |
| 月均新 Issue | 个位数 |
| 月均新 PR | 个位数 |
| 最近版本发布 | 2025-09 |
未来路线图
- 无公开的 v2.0 或重大功能路线图:Jason Quense 未在公开渠道披露重大功能计划。
- Standard Schema 兼容:目前 Yup 尚未宣布对 Standard Schema 互操作协议的支持,而 Zod 和 Valibot 已是该协议的成员。这可能在未来影响 Yup 与新一代表单库的集成便利性。
- 存量生态仍是价值:庞大的存量用户和 Formik 生态让 Yup 在可预见的 2–3 年内不会被淘汰,但新项目选型中已不再是首选。
综合评价
Yup 是一个久经考验的经典 Schema 校验库,它的链式 API 设计和 Formik 深度集成让其在 React 表单领域留下了深刻的印记。在 2026 年的技术格局下,Yup 更适合维护现有项目和对 Formik 有强依赖的场景,而新项目(尤其 TS-first、bundle 敏感项目)建议优先考虑 Zod 或 Valibot。