# Valibot vs Zod: Bundle Size and Tree-Shaking

> Valibot ships a schema in about 1.3 kB while Zod carries roughly 13 kB — here is why the modular pipe design tree-shakes and Zod's method chaining does not.

URL: https://www.matthewswong.com/en/blog/valibot-vs-zod-bundle-size/

- Author: Matthews Wong (https://www.matthewswong.com/en/about/)
- Published: 2026-07-14
- Updated: 2026-07-14
- Category: Web Dev

> **Key takeaway:** For bundle-sensitive frontends and edge functions, Valibot beats Zod on size: Valibot v1 ships around 1.3 kB gzipped because its schema and validation functions are separate, tree-shakeable modules. Zod v4 standard bundles everything at roughly 13 kB; the new zod/v4-mini export trims that to about 3.9 kB, but Valibot's modular pipe design still wins.

I reach for Zod on almost every TypeScript project I run. It is the default for a reason: the API is comfortable, the type inference is excellent, and the ecosystem around it is enormous. But on a recent project I was shipping validation into a Cloudflare Worker and watching the bundle budget like a hawk, and Zod's weight became a real problem. That is when I started taking Valibot seriously, and the difference is not marginal.

The core question is not which library validates better. Both are correct, both infer types cleanly, both cover the same shapes. The question is what ends up in your production bundle, and that comes down to a single architectural decision each library made about how you compose a schema.

## Why Zod's method chaining resists tree-shaking

Zod's classic API is method chaining on a single object. You import one thing and call methods off it. That ergonomic API is exactly what makes it hard to shrink. When you write the import below, the bundler pulls in the whole class graph because every method lives on the same object; a bundler cannot prove that you never call the string date parser or the discriminated union just because you did not type it here.

This is not a flaw so much as a trade-off. Method chaining reads beautifully and it is the reason so many of us fell in love with Zod. But the object that carries all those methods is one indivisible unit as far as the bundler is concerned.

## How Valibot's modular pipe design changes the math

Valibot inverts the design. Instead of methods on a class, every schema and every validation is a standalone function you import by name. Constraints are composed with a pipe function that threads a value through a sequence of actions. Because each action is its own exported function, the bundler keeps only the functions you actually reference and drops the rest. This is textbook tree-shaking, and it is why Valibot v1 lands around 1.3 kB gzipped for a typical schema.

> The wildcard import (import star as v) looks like it pulls in everything, but it does not. Modern bundlers like esbuild, Rollup, and Rolldown resolve which named exports you actually use and shake out the rest. The namespace import is just an ergonomic convenience, not a bundle-size cost.

## Zod v4 fought back with zod/v4-mini

Zod's maintainer clearly heard the bundle-size complaints. Zod v4, which landed in early 2025, introduced a separate zod/v4-mini export that abandons method chaining in favour of standalone check functions, much closer to Valibot's style. It brings the gzipped cost down to roughly 3.9 kB, a big improvement over the ~13 kB standard build. The catch is that the API is noticeably more verbose than classic Zod, and you give up some of the chaining ergonomics that made Zod pleasant in the first place.

## The comparison at a glance

| Dimension | Valibot v1 | Zod v4 (classic / mini) |
| --- | --- | --- |
| Gzipped size (typical schema) | ~1.3 kB | ~13 kB classic / ~3.9 kB mini |
| Composition model | Standalone functions + pipe() | Method chaining / .check() in mini |
| Tree-shakeable | Yes, by design | No (classic) / Yes (mini) |
| API ergonomics | Explicit, more imports | Very fluent (classic) / verbose (mini) |
| Ecosystem & adapters | Growing, good but smaller | Huge, de facto standard |
| Best fit | Edge, browser, size-critical | Node servers, existing Zod code |

## Which one I actually pick

- Server-side Node or NestJS APIs: I stay on Zod. Bundle size is irrelevant when the code runs on a long-lived server, and Zod's ecosystem, adapters, and familiarity win easily.
- Cloudflare Workers, Vercel Edge, or anything with a cold-start and a size limit: Valibot, without hesitation. Shaving ten-plus kilobytes off every deploy matters when the platform caps you.
- Client-side form validation in a browser bundle: Valibot if the page is performance-critical, otherwise either is fine.
- A shared schema used on both frontend and backend: pick the one whose weight the frontend can tolerate, since the backend does not care either way.

> Do not migrate a large existing Zod codebase to Valibot just to save kilobytes on the server. The refactor cost, the loss of Zod-specific adapters, and the risk of subtle validation differences almost never pay off unless bundle size is a hard, measured constraint. Measure first, then decide.

The honest summary: Valibot won the bundle-size argument so convincingly that Zod restructured its own API to answer it. That is the strongest endorsement Valibot could get. But Zod is not standing still, and for most server work its ergonomics and ecosystem still make it my default. Choose based on where the code runs, not on which library is trendier this quarter.

## Sources

- Valibot v1 — The 1 kB schema library (official blog)
- Zod Mini — official documentation
- Zod vs Valibot bundle size comparison (anatoo/zod-vs-valibot)

## Source links

- https://valibot.dev/blog/valibot-v1-the-1-kb-schema-library/
- https://zod.dev/packages/mini
- https://github.com/anatoo/zod-vs-valibot

## FAQ

### Is Valibot really smaller than Zod?

Yes, and by a large margin for typical schemas. Valibot v1 lands around 1.3 kB gzipped because each schema and validation is a separate tree-shakeable function. Classic Zod v4 is roughly 13 kB because its method-chaining API bundles everything into one object, and even the newer zod/v4-mini export is about 3.9 kB.

### Why can't Zod's classic API be tree-shaken?

Zod's classic API chains methods off a single object, so every validator lives on the same class. A bundler cannot prove you never call a given method just because it does not appear in your code, so it keeps the whole runtime. Valibot avoids this by making every validation a standalone exported function.

### Does the wildcard import in Valibot pull in the whole library?

No. Writing an import-star-as-v statement looks like it imports everything, but modern bundlers such as esbuild, Rollup, and Rolldown analyse which named exports you actually reference and drop the rest. The namespace import is purely an ergonomic convenience with no bundle-size penalty.

### Should I migrate my existing Zod code to Valibot?

Usually not, unless bundle size is a hard, measured constraint like an edge-function size limit. The refactor cost, the loss of Zod-specific adapters, and the risk of subtle validation differences rarely pay off on the server, where bundle size is irrelevant. Measure first, then decide.

### What is zod/v4-mini and when should I use it?

zod/v4-mini is a tree-shakeable export introduced in Zod v4 that replaces method chaining with standalone check functions, bringing the gzipped cost down to roughly 3.9 kB. Use it when you want to stay in the Zod ecosystem but need a smaller bundle for the browser or edge. It is more verbose than classic Zod but still larger than Valibot.

---

- HTML version: https://www.matthewswong.com/en/blog/valibot-vs-zod-bundle-size/
- Bahasa Indonesia: https://www.matthewswong.com/id/blog/valibot-vs-zod-bundle-size/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
