Zod vs Yup vs Valibot (2026 Comparison)
Schema validation is essential for forms, APIs, and data processing. Zod is the TypeScript-first standard. Yup is the battle-tested veteran. Valibot is the tiny newcomer. Here's the real comparison.
Quick Verdict
- Zod — Best overall. TypeScript-first, most ecosystem support.
- Yup — Best for existing projects. Proven, familiar API.
- Valibot — Best for bundle size. Tree-shakeable, modular design.
API Comparison
Zod
import { z } from 'zod'
const userSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().min(18).optional(),
})
type User = z.infer<typeof userSchema> // TypeScript type auto-inferred
const result = userSchema.safeParse(data)
if (result.success) {
console.log(result.data) // Typed as User
}
Yup
import * as yup from 'yup'
const userSchema = yup.object({
name: yup.string().min(2).required(),
email: yup.string().email().required(),
age: yup.number().min(18),
})
type User = yup.InferType<typeof userSchema>
const result = await userSchema.validate(data)
Valibot
import * as v from 'valibot'
const userSchema = v.object({
name: v.pipe(v.string(), v.minLength(2)),
email: v.pipe(v.string(), v.email()),
age: v.optional(v.pipe(v.number(), v.minValue(18))),
})
type User = v.InferOutput<typeof userSchema>
const result = v.safeParse(userSchema, data)
Key Differences
| Feature | Zod | Yup | Valibot |
|---|---|---|---|
| Bundle size (min+gzip) | ~13KB | ~12KB | ~1-5KB (tree-shaked) |
| TypeScript-first | ✅ | ❌ (added later) | ✅ |
| Type inference | Best | Good | Best |
| Tree-shakeable | ❌ | ❌ | ✅ |
| Async validation | ✅ | ✅ (default) | ✅ |
| Sync validation | ✅ (default) | ✅ | ✅ (default) |
| Error messages | Good | Good | Good |
| Ecosystem | Largest | Large | Growing |
Bundle Size
This is Valibot's killer feature:
| Library | Full import | Typical usage |
|---|---|---|
| Zod | 13KB | 13KB (not tree-shakeable) |
| Yup | 12KB | 12KB (not tree-shakeable) |
| Valibot | 12KB | 1-5KB (only used functions) |
Valibot uses a modular, functional design. Import only what you use. For client-side validation where every KB matters, Valibot saves 8-12KB.
For server-side: Bundle size doesn't matter. Use Zod. For client-side (mobile, edge): Valibot's size advantage is real.
TypeScript Integration
Zod
The gold standard. z.infer<typeof schema> gives you a TypeScript type from any schema. Works perfectly with tRPC, React Hook Form, and the Vercel AI SDK.
Yup
TypeScript support added after initial release. InferType works but edge cases exist. Less type-safe than Zod for complex schemas.
Valibot
Excellent TypeScript support, comparable to Zod. InferOutput and InferInput for transform scenarios.
Winner: Zod and Valibot tied. Both are TypeScript-first.
Form Library Integration
| Library | React Hook Form | Formik | TanStack Form |
|---|---|---|---|
| Zod | ✅ (@hookform/resolvers) | ❌ | ✅ |
| Yup | ✅ (@hookform/resolvers) | ✅ (built-in) | ✅ |
| Valibot | ✅ (@hookform/resolvers) | ❌ | ✅ |
All three work with React Hook Form (the dominant form library). Yup has native Formik support (same creator).
Framework Integration
| Zod | Yup | Valibot | |
|---|---|---|---|
| tRPC | ✅ (default) | ✅ | ✅ |
| Next.js Server Actions | ✅ (zod) | ✅ | ✅ |
| Astro | ✅ | ✅ | ✅ |
| Drizzle ORM | ✅ (drizzle-zod) | ❌ | ✅ (drizzle-valibot) |
| Vercel AI SDK | ✅ (default) | ❌ | ❌ |
| Hono | ✅ (@hono/zod-validator) | ❌ | ✅ (@hono/valibot-validator) |
Zod has the largest ecosystem by far. Most tools default to Zod.
Performance
Validation speed (operations/second for a typical object):
| Zod | Yup | Valibot | |
|---|---|---|---|
| Simple object | ~2M/s | ~500K/s | ~3M/s |
| Complex nested | ~500K/s | ~150K/s | ~800K/s |
Valibot is fastest. Yup is slowest (async by default adds overhead). In practice, all three are fast enough — validation is rarely a bottleneck.
Error Handling
Zod
const result = schema.safeParse(data)
if (!result.success) {
result.error.issues // Array of { path, message, code }
}
Flat error format with flatten() for form-friendly errors.
Yup
try {
await schema.validate(data, { abortEarly: false })
} catch (err) {
err.inner // Array of ValidationError
}
Valibot
const result = v.safeParse(schema, data)
if (!result.success) {
result.issues // Array of { path, message, kind }
}
All three provide clear error messages. Zod and Valibot have slightly better developer ergonomics.
When to Use Each
Choose Zod When
- TypeScript project (default choice)
- Using tRPC, Vercel AI SDK, or Hono
- Need the largest ecosystem and community
- Server-side validation (bundle size doesn't matter)
- Most tutorials and examples use Zod
Choose Yup When
- Existing project already using Yup
- Using Formik (native integration)
- Team is familiar with Yup's API
- Don't want to migrate without a reason
Choose Valibot When
- Bundle size is critical (client-side, mobile, edge)
- Want the fastest validation performance
- Building a library or framework
- Tree-shaking matters (only ship what you use)
FAQ
Should I migrate from Yup to Zod?
Only if Yup's TypeScript limitations are causing issues. Migration takes time and both work fine.
Is Valibot production-ready?
Yes. It's been stable since v0.30+ and is used in production by several projects.
Can I use Zod for form validation?
Yes. @hookform/resolvers/zod with React Hook Form is the standard pattern.
What about ArkType?
ArkType is another TypeScript-first validation library with excellent performance. It's worth watching but has a smaller ecosystem than Zod.
Bottom Line
Zod is the standard for TypeScript validation in 2026. Largest ecosystem, best integration with modern tools, excellent DX. Valibot is the better choice when bundle size matters (client-side, edge, mobile). Yup is fine for existing projects but not the choice for new ones.
Default: Zod. Optimize: Valibot. Legacy: Yup.