Capítulo 39 de 61
Zod can compile a schema into a specialized fast-path validator (canary-only feature, install zod@canary) that produces identical results and identical errors to the standard parser, with a median 2.4x speedup that scales with how much per-node work the schema does.
z.compile(schema): eagerly compiles one schema, returning a clone with the fast path installed; .parse(), .safeParse(), inference, and composition all work normally on the clone. Methods that derive a new schema (.refine(), .extend(), .optional(), .meta(), ...) return uncompiled schemas — always compile the final schema, not an intermediate one.import "zod/compile": enables compilation globally; every schema constructed after this import compiles lazily on its first parse. Import order matters — place it before any module that defines schemas.ZodError — so there's no compiled error format to drift out of sync. Consequence: invalid inputs pay for both the fast path attempt and the fallback, and refinements/transforms may run twice on invalid input (never more than twice; exactly once on valid input).ZodCompileAsyncError); z.xor(), custom when conditions on checks, recursive schemas, z.coerce.*, and .catch() with a callback (vs. a constant, which compiles fine) all raise ZodCompileUnsupportedError. Inside containers, an unsupported child schema just runs on the standard parser while the rest stays compiled — except a callback-based .catch(), which blocks compilation of the whole schema it's attached to.new Function, unavailable under strict CSP. z.config({ jitless: true }) disables global-mode compilation automatically; calling z.compile() directly in a jitless environment throws.const Player = z.object({ username: z.string(), xp: z.number() });
const CompiledPlayer = z.compile(Player); // fast-path clone; Player itself is unchanged
// compile LAST — refine() on an already-compiled schema returns an uncompiled result
const wrong = z.compile(z.string()).refine((val) => val.length > 1); // not compiled
const right = z.compile(z.string().refine((val) => val.length > 1)); // compiled
import "zod/compile"; // before any schema-defining module
| Schema shape | Approximate speedup |
|---|---|
z.array(z.string()), 100 items | ~14x |
| 20-key object | ~9x |
| discriminated union | ~4x |
| 5-key object | ~2.5x |
bare z.string() | none (no dispatch to remove) |
.refine()/.extend()/etc.: those methods return a new, uncompiled schema — compile only the final version.import "zod/compile" global mode inside a library: it silently affects every consumer's schemas; leave that opt-in decision to the application, not a library dependency.z.string() gains nothing..parse()/.safeParse() behave identically on compiled and uncompiled schemas.