Yup logo

Yup

一个简洁、声明式的 JavaScript/TypeScript 对象 Schema 校验库,与 Formik 深度集成,是 React 表单校验生态中最经典的校验方案。

精选工具表单校验Schema验证Formik链式 API

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 为主文档)
  • GitHubhttps://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

核心概念与架构

核心概念

  1. Schema(模式):Yup 的核心抽象。每个数据类型(stringnumberbooleandatearrayobjectmixed)都是一个 Schema 工厂,返回可链式调用的 Schema 实例。
  2. Validation(校验):通过 validate() / validateSync() 对输入值执行规则检查,失败时抛出 ValidationError
  3. Casting(类型转换)cast() 方法在运行校验前,先将输入值转换为 Schema 声明的目标类型(如字符串 '25' → 数字 25)。
  4. Transform(自定义转换):通过 .transform() 插入自定义的类型转换逻辑,在 cast 阶段执行。
  5. Test(自定义规则):通过 .test() 添加完全自定义的校验逻辑,可访问 Schema 上下文(父对象、兄弟字段等)。
  6. When / Condition(条件 Schema):根据其他字段的值动态调整校验规则。
  7. 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) 风格流式定义校验规则,可读性强、上手快。
  • 完善的内置类型stringnumberbooleandatearrayobjectmixedlazyref,覆盖绝大多数业务场景。
  • 异步校验支持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/yupVue 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() 提供了强大的声明式条件能力。

开发与工程化

开发流程

  1. Schema 定义阶段:将业务数据模型翻译为 Yup Schema,每个字段对应一条链式规则。
  2. 单元测试:对关键 Schema 编写 .isValid() / .validateSync() 测试,覆盖正常与异常边界。
  3. 表单集成:将 Schema 传入 Formik validationSchema 或 React Hook Form 的 resolver
  4. 错误消息国际化:使用 setLocale() 配合 i18next 等框架注入多语言消息。
  5. 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(&#123;...&#125;)).min(1000))在元素过多时性能下降明显。
  • 深度嵌套对象(> 5 层)的 describe()validate() 有额外开销。
  • 没有 tree-shaking,即使只用了 yup.string(),也会打包整个库。

技术对比

维度YupZodValibot
包体积~18–30 KB~12–15 KB< 2 KB(tree-shakeable)
校验速度中等快(V8 优化好)快(复杂 Schema 最优)
TypeScript 推断良好(InferType优秀(精确推断)优秀(精确推断)
Tree-shaking❌ 不支持❌ 不支持✅ 完整支持
异步校验✅ 原生支持✅ 原生支持✅ 原生支持
类型转换✅ 内置 cast❌ 需手动❌ 需 pipeline
条件 Schemawhen() 强大refine / superRefineif 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
  })

常见陷阱

  • validate vs validateSyncvalidate 是异步的,返回 Promise;在同步代码中误用会拿到 Promise 对象而非数据。
  • cast 静默失败cast() 对无法转换的值默认返回原值,而非抛出异常。需要严格转换时使用 cast(value, &#123; strict: true &#125;)
  • whenis 条件is 字段可以是值、函数或 Schema,混用容易出错,建议统一使用函数形式。
  • Schema 实例共享:Yup Schema 是不可变的,可以在多个表单间安全复用——但不要在其上误用 concat() 并期望原实例改变。
  • 数组元素校验yup.array().of(schema) 中,空数组 [] 默认是合法的,如需必填数组要显式加 .required().min(1)
  • TypeScript 类型同步yup.InferType 推断的类型在复杂条件 Schema(when)下可能不准确,关键场景建议手动定义类型。

技术局限与边界

已知限制

  1. 无 Tree-shaking:Yup 的模块结构不支持 tree-shaking,即使只使用 yup.string(),整个库(~18–30 KB)都会被打包。在包体积极度敏感的场景(边缘函数、嵌入式 widget)下是明显劣势。
  2. TypeScript 类型推断有限InferType 在条件 Schema(when)、lazy() 和复杂嵌套场景下无法精确推断,通常需要手动补全类型。
  3. API 设计偏老:Yup 的链式 API 设计于 TypeScript 全面普及之前,部分高级类型场景下类型推断不如 Zod / Valibot 流畅。
  4. 无 Schema 序列化:Yup Schema 无法序列化到 JSON,不能在服务端与客户端之间传递 Schema 定义,也不支持从 Schema 生成 JSON Schema。
  5. 社区活跃度下降:2024–2026 年,Yup 的新增 star 速度明显放缓(每月仅个位数),新特性和重大修复较少,进入维护模式。
  6. 新项目采用率下降: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 不高。

学习资源

官方文档

教程

社区资源

2026 年现状

最新版本

  • 当前稳定版1.7.1(2025-09-21 发布)
  • 发布节奏:2025 年发布了 1.7.01.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。