Valibot vs Zod v4 in 2026: Bundle Size and Speed
TL;DR
Valibot for bundle-critical apps; Zod v4 for ecosystem and ergonomics. Zod v4 is a major leap: 14x faster string parsing, 57% smaller than v3, and the new Zod Mini build at 3.94 kB gzipped. Valibot v1.0 still wins on raw bundle size at 1.37 kB gzipped — 65% smaller than Zod Mini, 90%+ smaller than the full Zod v4 build. Runtime performance is now roughly equivalent. The real choice in 2026 comes down to tree-shaking needs, ecosystem integrations, and API preference.
Key Numbers at a Glance
| Valibot v1.0 | Zod v4 (Standard) | Zod v4 (Mini) | Zod v3 | |
|---|---|---|---|---|
| Gzipped size | 1.37 kB | ~5 kB | 3.94 kB | ~12 kB |
| String parse speed | baseline | ~14x faster than v3 | ~14x faster than v3 | baseline |
| npm weekly downloads | ~1M | ~15M | ~15M | ~15M |
| Tree-shaking | Per-import | Partial (Mini: full) | Full | Partial |
| JSON Schema output | via plugin | Built-in (z.toJSONSchema()) | Built-in | No |
| Stable release | v1.0 (2025) | v4 (2025) | v4 (2025) | v3 (2020) |
Bundle Size Breakdown
Bundle size is where Valibot has always had the clearest advantage, and it still holds in 2026 — but the gap has closed.
Valibot 1.37 kB gzipped is the result of its core design: every validator (string, email, minLength, etc.) is a separate named import. Your bundler only includes what you use. A schema that validates a single email string pulls in barely any code.
Zod v4 Standard (~5 kB gzipped) dropped from 12 kB in v3 — a 57% reduction — by eliminating deprecated APIs, restructuring internals, and tightening the core. For most apps, 5 kB is entirely acceptable.
Zod Mini (3.94 kB gzipped) is new in v4 and is the most direct response to Valibot. It ships with full tree-shaking support via a pipe-based API that mirrors Valibot's style. You get the Zod ecosystem with much better bundler efficiency.
Even so, Valibot at 1.37 kB is still 65% smaller than Zod Mini. If you're building for edge functions, Cloudflare Workers, or any environment where cold-start bundle weight matters, that difference is real.
Performance
For years, Valibot had a measurable speed edge over Zod v3. Zod v4 closes that gap significantly.
Zod v4 vs Zod v3 benchmarks (from zod.dev/v4):
- String parsing: 14x faster
- Array parsing: 7x faster
- Object parsing: 6.5x faster
In practice, this means Zod v4 and Valibot v1.0 are now in the same performance tier for real-world schemas. You won't feel a runtime difference in typical API validation workloads.
A note on the "Zod v4 got 17x Slower" controversy: A dev.to article circulated in 2025 making this claim. It measured a specific synthetic benchmark edge case — deeply nested recursive schemas under unusual conditions — not representative workloads. The overall picture from the official benchmarks and community testing is that Zod v4 is substantially faster than v3 across common patterns. The controversy was overblown.
ArkType deserves a mention: it's still 3–4x faster than both Zod and Valibot, using a string-literal API. If raw throughput is your primary constraint, ArkType is worth evaluating, though its API style is notably different.
API Comparison
Zod v4
Zod v4 adopts a more explicit pipe-based approach for refinements, though it retains the classic chained-method ergonomics for common cases.
import { z } from "zod";
// Basic object schema — same as v3
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
age: z.number().int().min(0).max(120),
role: z.enum(["admin", "user", "guest"]),
});
type User = z.infer<typeof UserSchema>;
// v4: .email() is now a pipe internally; explicit pipe for custom refinements
const EmailSchema = z.string().pipe(z.email());
// New in v4: JSON Schema output
const jsonSchema = z.toJSONSchema(UserSchema);
// { type: "object", properties: { id: { type: "string", format: "uuid" }, ... } }
// Async validation
const AsyncUserSchema = z.object({
username: z.string().refine(async (val) => {
const exists = await checkUsernameExists(val);
return !exists;
}, "Username already taken"),
});
Valibot v1.0
Valibot's pipe-based API has been consistent since its inception. Every transform and validation step is explicit and individually tree-shakeable.
import * as v from "valibot";
// Basic object schema
const UserSchema = v.object({
id: v.pipe(v.string(), v.uuid()),
email: v.pipe(v.string(), v.email()),
age: v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(120)),
role: v.picklist(["admin", "user", "guest"]),
});
type User = v.InferOutput<typeof UserSchema>;
// Every validator is a separate import — bundler only ships what you use
const EmailSchema = v.pipe(v.string(), v.email());
// Async validation
const AsyncUserSchema = v.objectAsync({
username: v.pipeAsync(
v.string(),
v.checkAsync(async (val) => {
const exists = await checkUsernameExists(val);
return !exists;
}, "Username already taken")
),
});
Zod Mini
Zod Mini adopts Valibot's pipe-first style to enable tree-shaking:
import { z, pipe, string, email, object, uuid } from "zod/mini";
const UserSchema = object({
id: pipe(string(), uuid()),
email: pipe(string(), email()),
});
type User = z.infer<typeof UserSchema>;
Ecosystem and Integrations
This is where Zod wins decisively, and it's a significant practical consideration.
Zod's ecosystem (as of March 2026):
- tRPC — Zod is the default and first-class input/output validator
- Drizzle ORM —
createSelectSchema()/createInsertSchema()generate Zod schemas from your database tables - React Hook Form —
@hookform/resolvers/zodis the most popular resolver - OpenAPI / Swagger — multiple generators (zod-to-openapi, @asteasolutions/zod-to-openapi)
- Prisma — zod-prisma-types generates schemas from your Prisma schema
- Next.js Server Actions — zod is the community-standard for validating action inputs
Valibot's ecosystem is growing but lags significantly. Most of these integrations either don't support Valibot or have it as a secondary option. The @hookform/resolvers package added a Valibot resolver, and tRPC has community adapters, but you're more likely to hit a library that only documents Zod.
If your project uses tRPC, Drizzle, or React Hook Form heavily, picking Valibot means maintaining adapter shims or accepting less official support.
Migration: Zod v3 to v4
Zod v4 has breaking changes worth knowing before upgrading:
.email(),.url(),.uuid()are now pipe-based internally (behavior unchanged, but custom error messages syntax changed)- Several deprecated methods removed (
z.string().nonempty()→z.string().min(1)) - Error formatting API restructured
z.ZodErrorstill works;z.treeifyError()is the new recommended error formatter
The official migration guide at zod.dev/v4 covers the full list. For most projects the migration is a few hours of find-and-replace plus testing. For large codebases with heavy .email()/.url() error message customization, budget more time.
There is no migration path from Valibot to Zod or vice versa — the APIs are different enough that switching means rewriting schemas.
When to Use Valibot
- Edge functions / Cloudflare Workers: Every byte matters. 1.37 kB vs 5 kB is a real difference at the edge.
- Micro-frontends or shared packages: Tree-shaking per-import means consumers only pay for what they import.
- You control the full stack: When you don't depend on tRPC, Drizzle, or other Zod-integrated libraries, Valibot's lighter footprint has no downside.
- You prefer the explicit pipe API: Valibot's API makes every validation step visible and intentional.
- Bundle size is a primary product requirement: Mobile web, Lighthouse scores, Core Web Vitals — if you're optimizing for these, Valibot's size advantage compounds with scale.
When to Use Zod v4
- tRPC, Drizzle ORM, React Hook Form: The ecosystem integrations work out of the box and are actively maintained.
- You're migrating from Zod v3: The path is documented and manageable; switching to Valibot would require full schema rewrites.
- You need JSON Schema output:
z.toJSONSchema()is built-in and produces spec-compliant output without plugins. - Team familiarity: Zod is what most TypeScript developers already know. The ergonomics are well-documented and widely discussed.
- General-purpose API validation: For typical Node.js backend services where bundle size is not a constraint, Zod v4 at ~5 kB is fine.
When to Use Zod Mini
- You want the Zod ecosystem and ecosystem integrations, but bundle size is a genuine constraint.
- You're building a library that will be consumed by others and want to minimize peer dependency weight.
- You're willing to adopt the pipe-based API style (which gives up some of the classic Zod ergonomics).
Comparison: Validation Error Handling
// Zod v4
const result = UserSchema.safeParse(input);
if (!result.success) {
const errors = z.treeifyError(result.error);
// { email: { _errors: ["Invalid email"] }, age: { _errors: ["Too small"] } }
}
// Valibot v1.0
const result = v.safeParse(UserSchema, input);
if (!result.success) {
const issues = result.issues;
// [{ path: [{ key: "email" }], message: "Invalid email" }, ...]
const flat = v.flatten(result.issues);
// { nested: { email: ["Invalid email"], age: ["Value must be ≥0"] } }
}
Both provide structured error output. Zod's treeifyError produces a nested object matching your schema shape, which maps well to form field errors. Valibot's flatten does similar work. Neither has a clear ergonomic edge here — it's preference.
Summary Scorecard
| Category | Valibot v1.0 | Zod v4 | Zod Mini |
|---|---|---|---|
| Bundle size | Winner (1.37 kB) | 3rd (~5 kB) | 2nd (3.94 kB) |
| Runtime speed | Tied | Tied | Tied |
| Tree-shaking | Best | Partial | Full |
| Ecosystem | Limited | Best | Best |
| JSON Schema | Plugin | Built-in | Built-in |
| API ergonomics | Pipe-explicit | Familiar chains | Pipe-explicit |
| Migration support | — | v3→v4 guide | v3→v4 guide |
| TypeScript inference | Full | Full | Full |
| Async validation | Yes | Yes | Yes |
| Weekly downloads | ~1M | ~15M | ~15M |
Methodology
Performance numbers for Zod v4 are sourced from the official Zod v4 release documentation at zod.dev/v4, which includes benchmark results comparing v4 and v3 across string, array, and object parsing scenarios.
Bundle sizes are measured as gzipped output using Rolldown (as documented for Zod Mini) and the standard Rollup/esbuild pipeline for Valibot. Sizes reflect the core library only; actual app bundle impact depends on which validators you import and your bundler's tree-shaking implementation.
Valibot's size and API documentation is sourced from valibot.dev and the Valibot comparison guide.
npm weekly download figures are approximate, sourced from npmjs.com, as of March 2026. Zod download counts reflect combined v3 and v4 installs during the v4 transition period.
The "Zod v4 17x slower" claim referenced in this article refers to a synthetic benchmark published on dev.to that measured a specific recursive schema edge case and is not representative of general validation workloads.
Related Reading
- Joi vs Zod in 2026 — if you're migrating off Joi
- class-validator vs TypeBox vs io-ts — decorator and functional validation alternatives
- dotenv vs t3-env vs envalid for env validation — schema validation applied to environment variables
See the live comparison
View valibot vs. zod on PkgPulse →