Three good answers to the same problem
Runtime validation in TypeScript solves a gap the compiler can't: types vanish at build time, so data crossing a boundary — an API response, a form, an env var, an LLM's JSON output — needs *runtime* checking. Zod, Valibot, and ArkType are the three leading answers in 2026, and thanks to Standard Schema they're largely interchangeable with the tools around them. The differences are in performance, bundle size, and syntax. Here's how to choose.
Zod v4 — the default, now fast
Zod has long been the ecosystem default (30M+ weekly downloads), historically chosen for developer experience over raw speed. Zod v4 changed the calculus: it's dramatically faster than v3 (roughly 4x on typical parsing, with much bigger gains on string-heavy schemas), ships a smaller core, and closed most of the performance gap that used to push people to alternatives.
import { z } from "zod";
const User = z.object({
name: z.string().min(1),
email: z.string().email(),
age: z.number().int().positive().optional(),
});
type User = z.infer<typeof User>; // types inferred from the schema
const result = User.safeParse(input); // { success, data } | { success, error }Zod v4 also introduced Zod Mini, a tree-shakable variant with a functional API for bundle-sensitive projects. Its superpower remains the ecosystem: the most integrations, the most Stack Overflow answers, and z.infer DX that's hard to beat. Pick Zod when you want the safe default with the largest ecosystem and don't have an extreme bundle constraint.
Valibot — modular and tiny
Valibot's headline is bundle size. Instead of chained methods on a schema object, validations are standalone functions you *pipe* together, so a bundler tree-shakes away everything you don't use. A real login schema can come out around 1–2KB versus Zod's larger footprint — often an order of magnitude smaller.
import * as v from "valibot";
const User = v.object({
name: v.pipe(v.string(), v.minLength(1)),
email: v.pipe(v.string(), v.email()),
age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))),
});
type User = v.InferOutput<typeof User>;
const result = v.safeParse(User, input);That modular design also tends to be fast. The trade-off is a slightly more verbose pipe style and a smaller (though growing) ecosystem. Pick Valibot when bundle size is a first-class concern — edge functions, serverless, client-heavy apps, anything shipped to the browser where every KB counts.
ArkType — types as the syntax
ArkType takes a different philosophy: you write schemas as TypeScript-like type strings, and it derives both the runtime validator and the static type from the same definition. It's known for extremely fast validation and a syntax that feels native to anyone who already thinks in TypeScript.
import { type } from "arktype";
const User = type({
name: "string > 0",
email: "string.email",
"age?": "number.integer > 0",
});
type User = typeof User.infer;
const result = User(input); // returns data or an ArkErrors objectThe string-based DSL is expressive and concise, and performance is a selling point. The cost is a learning curve for the syntax and, again, a smaller ecosystem than Zod. Pick ArkType when you value a type-native feel and top-tier validation speed and are comfortable with its DSL.
Side-by-side
| Zod v4 | Valibot | ArkType | |
|---|---|---|---|
| Bundle size | Moderate (Mini is smaller) | Tiny (modular, tree-shakable) | Small–moderate |
| Performance | Fast (big v4 jump) | Fast | Very fast |
| Syntax | Chained methods | Piped functions | Type-string DSL |
| Ecosystem | Largest | Growing | Growing |
| Standard Schema | Yes | Yes | Yes |
| Best for | Default choice, max ecosystem | Bundle-sensitive apps | Type-native DX, speed |
How to actually decide
Because all three implement Standard Schema, the surrounding tools don't lock you in — so decide on the two axes that differ most:
- Is bundle size critical? (edge, serverless, client-shipped) → Valibot.
- Do you want the safest default and biggest ecosystem? → Zod v4 (reach for Zod Mini if the bundle gets tight).
- Do you want a type-native DSL and maximum speed, and don't mind a newer ecosystem? → ArkType.
For most teams starting today, Zod v4 is the pragmatic default — the old "Zod is slow" reason to avoid it is largely gone, and the ecosystem advantage is real. Reach for Valibot when the bytes matter. To generate a starting schema from existing data, use JSON to Zod, and for the document-format side see JSON Schema vs Zod vs Pydantic.