Why Schema Validation Matters
Schema validation libraries validate data at runtime — form inputs, API responses, environment variables, configuration files. In TypeScript projects, they also infer types from schemas, creating a single source of truth for both runtime validation and compile-time type checking. Zod, Yup, and Valibot are the three most popular options. Each takes a different approach to API design, bundle size, and TypeScript integration.
Zod: The TypeScript Standard
Zod is the most popular validation library in the TypeScript ecosystem. Its API is chain-based: z.string().email().min(5). TypeScript type inference is excellent — z.infer<typeof schema> gives you the exact type from any schema. Zod is ~12KB gzipped, supports transforms, refinements, discriminated unions, and recursive schemas. It's the default choice for tRPC, which uses Zod schemas for end-to-end type safety. If you're unsure which to pick, Zod is the safe default.
Yup: The Original
Yup pioneered JavaScript schema validation. Its API is similar to Zod: yup.string().email().required(). Yup has been the default validation library for Formik and React Hook Form for years. Its TypeScript support has improved but isn't as precise as Zod's — complex schemas sometimes produce any types. Yup's main advantage is familiarity and ecosystem integration. If your team already uses Yup and it works, there's no urgent reason to switch. For new projects, Zod is a better choice.
Valibot: The Lightweight Champion
Valibot takes a radically different approach: functional, modular, and tree-shakeable. Instead of chaining methods on objects, you compose functions: pipe(string(), email(), minLength(5)). The result: your bundle only includes the validation functions you actually use. A typical Valibot schema adds less than 1KB to your bundle, compared to Zod's 12KB flat tax. For client-side form validation where bundle size matters, Valibot is compelling. Its TypeScript inference matches Zod's quality.
API Comparison
Zod: z.object({ name: z.string(), age: z.number().min(0) }). Chain-based, concise, familiar. Yup: yup.object({ name: yup.string().required(), age: yup.number().min(0) }). Very similar to Zod. Valibot: object({ name: string(), age: pipe(number(), minValue(0)) }). Functional composition. All three APIs are readable and ergonomic. Zod and Yup feel more natural to OOP-style developers. Valibot appeals to functional programming enthusiasts.
Performance & Bundle Size
Valibot wins bundle size decisively: under 1KB for typical schemas vs Zod's ~12KB vs Yup's ~15KB. For validation speed, all three are fast enough for form validation (microseconds). For API validation at scale (thousands of requests/second), benchmarks show Valibot is 2-3x faster than Zod, which is 2x faster than Yup. In practice, validation performance is rarely a bottleneck. Bundle size matters more for client-side apps; validation speed matters more for high-throughput APIs.
Ecosystem Integration
Zod has the largest ecosystem: tRPC, React Hook Form (@hookform/resolvers), Astro content collections, Next.js Server Actions, and hundreds of libraries use Zod schemas. Yup has strong React Hook Form and Formik integration. Valibot has React Hook Form support and growing framework adoption but a smaller ecosystem. If you need ecosystem compatibility — especially tRPC — Zod is the only choice. For standalone form validation, any of the three works.
Which Should You Pick?
Choose Zod for: most TypeScript projects, tRPC integration, API validation, and when you want the largest ecosystem. It's the safe default. Choose Yup for: existing Formik/Yup codebases and teams familiar with Yup's API. No reason to migrate unless you need better TypeScript support. Choose Valibot for: client-side form validation where bundle size matters, performance-critical validation, and teams that prefer functional APIs. In 2026, Zod remains the default recommendation for new projects.