Skip to main content

Kanon vs Zod: Which Validation Library for TypeScript?

Zod is the most popular TypeScript schema validation library. It offers a fluent API, built-in transformations, and a large ecosystem. But its class-based architecture means every import pulls in the entire library, and its bundle size reflects that.

Kanon takes a different approach: pure functions, granular imports, and an optional JIT compiler for high-throughput scenarios. It covers the core validation use cases while staying significantly smaller. This page compares both libraries across the dimensions that matter in production.


At a Glance

AspectKanonZod v4 Classic
ArchitecturePure functionsClass-based
Tree-shakingPer-function importsLimited (class methods bundled together)
JIT compilationYes (2-10x faster)No
TransformationsCoercion only (native)Built-in (.transform())
DependenciesZeroZero
API compatibilityz shim for drop-in migration
Bundle (login form)~0.5 KB~12 KB

Bundle Size

The architectural difference drives the bundle gap. Zod uses classes: importing z.string() pulls in every method on the ZodString class. Kanon uses standalone functions: you import only what you validate.

For detailed per-scenario comparisons with auto-generated data, see the Kanon bundle size comparison.

// Kanon: only string() and object() end up in your bundle
import { string, object, parse } from "@pithos/core/kanon";

const loginSchema = object({
email: string({ format: "email" }),
password: string({ minLength: 8 }),
});
// Zod: the entire library ends up in your bundle
import { z } from "zod";

const loginSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});

Kanon's bundle grows proportionally with usage. Zod's is mostly fixed overhead.


Performance

Kanon offers two validation modes: a standard interpreter and a JIT compiler that generates optimized JavaScript validators at runtime.

For detailed benchmark results with auto-generated data, see the Kanon performance benchmarks.

ModeThroughputCSP Compatible
Kanon Standard~12.6M ops/sYes
Kanon JIT~23.6M ops/sNeeds unsafe-eval
Zod v4Varies by schemaYes

The JIT compiler analyzes your schema structure and emits a specialized validation function, avoiding the overhead of walking the schema tree on every call. For high-throughput scenarios (API servers, batch processing), this makes a measurable difference.


API Compatibility

Kanon provides a z shim that mirrors Zod's API for smooth migration:

// Just swap the import
import { z } from "@pithos/core/kanon/helpers/as-zod.shim";

// Your existing Zod code works unchanged
const userSchema = z.object({
name: z.string().min(1),
age: z.number().int(),
email: z.string().email(),
});

userSchema.parse(data);
userSchema.safeParse(data);

For a complete compatibility matrix, see the Kanon ↔ Zod interoperability page.

Coverage summary:

  • Primitives: 15/15 (100%)
  • Composites: 6/6 (100%)
  • Operators: 3/3 (100%)
  • Wrappers, refinements, coercion: 100%

Key Design Difference: Validation and Transformation are Separate

Kanon's native API focuses on validation. Coercion (coerceString, coerceNumber...) is the only built-in transformation: it converts the input type before validation. There are no chained .transform() pipelines like in Zod:

// Kanon: pure validation
parse(string(), " hello "); // ✅ Returns " hello " as-is

// Zod: validation + transformation
z.string().trim().parse(" hello "); // Returns "hello"

If you need to reshape data, handle it explicitly after validation.


Migration Guide

Ready to migrate? The complete step-by-step migration guide is in the Kanon module documentation: install, swap imports, handle edge cases, and optimize with direct imports. Go to migration guide →

Not sure which library fits your use case? See the comparison overview.


Further Reading