Zod validates everything now. Your tRPC routers. Your Fastify request bodies. Every structured output that comes back from an LLM in your agent pipeline. That is a lot of schema walking and Zod runtime interpreter model means it walks the entire schema tree on every single .parse()
call. Zod v4 added JIT compilation to ease the pain. A build plugin called zod-compiler, published in June 2026, goes further: it moves schema interpretation entirely out of your runtime before your code ships.
Two independent tools appeared within weeks of each other: zod-compiler
by Gajus Kuizinas and zod-aot
by wakita181009, solving the same problem from slightly different angles. When two developers independently build the same tool at the same time, the community has usually been sitting on real pain for a while.
The Problem With Runtime Schema Walking #
Zod uses an interpreter model. Your schema is a data structure, and Zod traverses it on every parse call: check the node type, apply constraints, collect errors, construct the result. Zod v4 improved this substantially with a JIT code generator called $ZodObjectJIT
that builds specialized validators using new Function()
at first parse. That is roughly 14x faster than v3.
But JIT has ceilings. The new Function()
constructor is blocked in Cloudflare Workers and strict CSP environments. Every cold Lambda or Edge function still pays the JIT compilation cost at boot. Set, Map, and Record schemas do not benefit from JIT at all. And when you chain .extend()
, .pick()
, or .omit()
, Zod performance regresses significantly. The schema shape is fixed at write time; the question is when you turn it into an optimized validator.
What AOT Compilation Does to Your Zod Schemas #
AOT compilation answers that question with: at build time. The same insight that made Angular templates fast and Vue 3 reactivity compiler-aware applies cleanly to validation: read the schema shape once, emit flat validators, ship them. No tree to walk at runtime, no per-node dispatch, no allocations per field.
Install the plugin:
npm install zod-compiler
Add it to your Vite config:
import zodCompiler from "zod-compiler/vite";
export default defineConfig({
plugins: [zodCompiler()],
});
Or webpack:
const { zodCompiler } = require("zod-compiler/webpack");
module.exports = {
plugins: [zodCompiler()],
};
That is the entire migration. The plugin scans your exported Zod schemas at build time, generates zero-overhead validators, and replaces the runtime calls transparently. Libraries that consume your schemas such as tRPC, Hono, and React Hook Form need no changes. Your source code stays identical.
The Performance Numbers #
Benchmarks from the author DEV post and from the competing zod-aot post:
- Medium objects with invalid input: approximately 30x faster than Zod v4
- Large objects with 100 fields: approximately 73x faster
- discriminatedUnion schemas: approximately 3.5x faster using O(1) switch dispatch instead of sequential trial
- Practical range across real schemas: 2 to 75x
The gains scale with schema complexity. Simple one-field schemas barely move. Complex nested objects with discriminated unions see the biggest improvements. If you are validating AI agent responses with nested JSON payloads and branching structures, you are in the high-gain zone. There is also a structural deduplication benefit: schemas that share shapes produce roughly 50% less generated output with no change in behavior.
Where It Works and Where It Won Not #
AOT compilation works on static, exported schemas. It does not work on:
Schemas with: these contain opaque functions the compiler cannot inline. The plugin falls back to standard Zod for these fields..transform()
,.refine()
, or.superRefine()
Dynamically constructed schemas: schemas built at runtime inside React component bodies or from user configuration are not visible to the build plugin.** Webpack and rspack environments**: virtual module URIs are not supported, so the plugin falls back to file-level helpers. It still works; the mechanism is slightly different.
Most production schemas are static exports. API validation layers, tRPC routers, Fastify schemas are defined once and imported everywhere. That is the exact profile where zod-compiler delivers.
The Other AOT Compiler: zod-aot #
zod-aot by wakita181009 arrived around the same time and uses a two-phase validation strategy: valid input returns immediately with zero allocations; invalid input triggers the full error path. It supports the same bundler ecosystem via unplugin, including rspack and Rolldown.
zod-compiler reportedly started as a fork of zod-aot before diverging. The main differences: zod-compiler has a persistent transform cache that is content-hash based and skips re-compilation of unchanged schemas, and handles shared schema deduplication at output level. If you need rspack or Rolldown support, zod-aot unplugin approach has broader coverage. Otherwise both are viable; zod-compiler has the more developed caching story.
The Verdict #
This is the lowest-friction performance upgrade in a TypeScript stack right now. One npm install, two lines in your bundler config, zero source changes. If your app validates complex schemas at any kind of throughput especially in an AI agent pipeline or a high-traffic API, the performance gains are substantial and the cost of adoption is nearly zero.
The tooling is weeks old, not years. Test it in staging, run your own benchmarks on your actual schemas, and check the upstream Zod AOT discussion for how this might eventually land in core. But do not wait for core; the community already shipped it.