Zod vs Yup
Which schema validation library should you use for your TypeScript project?
Comparison Table
| Zod | Yup | |
|---|---|---|
| TypeScript-first | ✓ Yes — types inferred from schema | Partial — requires separate types |
| Type inference | Automatic with z.infer<> | Manual (@types/yup or separate types) |
| Bundle size | ~14 KB (min+gzip) | ~23 KB (min+gzip) |
| Sync validation | ✓ parse() and safeParse() | Requires .validateSync() |
| Async validation | ✓ parseAsync() | ✓ .validate() (default async) |
| Error format | Flat errors via .flatten() | Nested errors via .inner |
| tRPC integration | ✓ Official support | Community support |
| React Hook Form | ✓ @hookform/resolvers/zod | ✓ @hookform/resolvers/yup |
| Next.js / Astro | ✓ Common pairing | ✓ Works fine |
| Performance | Generally faster | Slightly slower |
| Ecosystem maturity | Newer (2020), fast growing | Older (2016), established |
| Custom transforms | ✓ .transform() | ✓ .transform() |
Defining the Same Schema
Zod
import { z } from 'zod';
const UserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().int().min(18),
});
// TypeScript type inferred automatically
type User = z.infer<typeof UserSchema>;
// Parse
const user = UserSchema.parse(data);
// Safe parse
const result = UserSchema.safeParse(data);
if (result.success) {
console.log(result.data.name);
}Yup
import * as yup from 'yup';
const UserSchema = yup.object({
name: yup.string().min(2).required(),
email: yup.string().email().required(),
age: yup.number().integer().min(18).required(),
});
// TypeScript type requires manual inference
type User = yup.InferType<typeof UserSchema>;
// Validate (async by default)
const user = await UserSchema.validate(data);
// Validate without throwing
const isValid = await UserSchema.isValid(data);Choose Zod if:
- ✓ You are using TypeScript (it was designed for TS)
- ✓ You want types inferred from schemas, not defined twice
- ✓ You use tRPC, Next.js, or Astro
- ✓ You need synchronous validation (parse/safeParse)
- ✓ You want a smaller bundle
- ✓ Starting a new project from scratch
Choose Yup if:
- ✓ You have an existing codebase already using Yup
- ✓ Your team knows Yup well
- ✓ You rely heavily on async validation by default
- ✓ You are using Formik (Yup is the official pairing)
Generate a Zod schema from your JSON data?
Use the JSON to Zod Converter →