zod-compiler — новый плагин для сборщиков, который компилирует схемы Zod в валидаторы с нулевыми накладными расходами. Установите плагин, оставьте существующий код на Zod и получите ускорение валидации в 2–75 раз.
zod-compiler — это плагин времени сборки от Гайюса Куизинаса (автора Slonik и многих других TypeScript-инструментов), который компилирует схемы Zod в оптимизированные валидаторы. Он работает с Vite, webpack, esbuild, Rollup, Rolldown, rspack, Bun и Farm — то есть с любым современным сборщиком.
Ключевая идея в том, что runtime-валидация Zod обходит дерево схемы при каждом вызове:
для каждого z.string(), z.object() и z.union() Zod
проходит по внутреннему представлению и проверяет типы узел за узлом. Скомпилированный
валидатор сворачивает этот обход в единственное булево выражение — или switch-диспетчеризацию
для объединений — устраняя все накладные расходы на обход узлов.
Версия 1.13.1 опубликована в npm 17 июня 2026 года, проект набрал более 322 звёзд на GitHub и активно развивается. Протестирован в продакшен-проектах с десятками тысяч схем Zod.
z.object().parse(), .safeParse(), .shape, Standard Schema.is() с нулевым выделением памятиnpm install --save-dev zod-compiler
# или
pnpm add -D zod-compiler
# или
yarn add -D zod-compiler
Для Vite (самый распространённый вариант):
// vite.config.ts
import { defineConfig } from "vite";
import zodCompiler from "zod-compiler/vite";
export default defineConfig({
plugins: [zodCompiler()],
});
Для других сборщиков путь импорта меняется:
| Сборщик | Импорт |
|---|---|
| Vite | zodCompiler from "zod-compiler/vite" |
| webpack | zodCompiler from "zod-compiler/webpack" |
| esbuild | zodCompiler from "zod-compiler/esbuild" |
| Rollup | zodCompiler from "zod-compiler/rollup" |
| Rolldown | zodCompiler from "zod-compiler/rolldown" |
| rspack | zodCompiler from "zod-compiler/rspack" |
| Bun | zodCompiler from "zod-compiler/bun" |
| Farm | zodCompiler from "zod-compiler/farm" |
В автоматическом режиме (по умолчанию) плагин сканирует все файлы,
импортирующие из "zod", находит экспортированные схемы Zod и компилирует
их на этапе сборки. Ваши файлы со схемами остаются чистым Zod:
// src/schemas/user.ts — без изменений, чистый Zod
import { z } from "zod";
export const CreateUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.email(),
age: z.number().int().min(0).max(150),
role: z.enum(["admin", "editor", "viewer"]),
});
export const UpdateUserSchema = z.object({
name: z.string().min(1).max(100).optional(),
email: z.email().optional(),
});
Код использования тоже остаётся прежним:
import { CreateUserSchema } from "./schemas/user";
const user = CreateUserSchema.parse(data); // компилируется в оптимизированный валидатор
const result = CreateUserSchema.safeParse(data); // { success, data/error }
Смысл zod-compiler в том, что вам не нужно о нём думать. Установите плагин, настройте
один раз в конфиге сборки, и каждая схема Zod в проекте автоматически скомпилируется.
API — .parse(), .safeParse(), .parseAsync(),
.safeParseAsync() — остаётся идентичным.
Как показано выше: добавьте плагин, и каждая экспортированная схема Zod в проекте скомпилируется автоматически. Статический предфильтр пропускает файлы, чьи экспорты заведомо не могут быть схемами (функции, компоненты, константы), без их выполнения.
Автоматический режим также включает поднятие схем (schema hoisting) — схемы, определённые внутри функций (компоненты React, обработчики запросов, хелперы), перемещаются на уровень модуля:
// До: схема пересоздаётся при каждом вызове
function getSchema() {
return z.object({ name: z.string() });
}
// После (результат сборки): схема создаётся один раз при загрузке модуля
const _zh_schema = z.object({ name: z.string() });
function getSchema() {
return _zh_schema;
}
Это значит, что схема внутри React-компонента, проверяющая пропсы, или внутри обработчика запроса, создаётся один раз при загрузке модуля, а не при каждом вызове. Компилятор также дедуплицирует идентичные схемы в единую привязку.
compile()
Если вы предпочитаете явное включение, оберните отдельные схемы в compile():
import { z } from "zod";
import { compile } from "zod-compiler";
const UserSchema = z.object({
name: z.string().min(3),
email: z.email(),
});
export const validateUser = compile(UserSchema);
// В dev: использует runtime Zod
// После сборки: AOT-скомпилированный валидатор
validateUser.parse(data);
В паре с schemas: "explicit" в опциях плагина compile()
становится единственным путём компиляции — автоматическое сканирование отключается.
Это идеально для постепенного внедрения в больших кодовых базах.
Для проектов без сборщика или для разовой компиляции:
# Один файл
npx zod-compiler generate src/schemas.ts -o src/schemas.compiled.ts
# Директория
npx zod-compiler generate src/ -o src/compiled/
# Режим отслеживания
npx zod-compiler generate src/ --watch
# Удаление неизвестных ключей из вывода z.object()
npx zod-compiler generate src/ --strip-unknown-keys
Бенчмарк сравнивает zod-compiler с Zod v3, Zod v4, Typia и AJV. Результаты в ops/s (выше — лучше), измерено на Apple M4 Max.
| Сценарий | Zod v4 | zod-compiler | vs Zod v4 |
|---|---|---|---|
| Простая строка | 14.4M | 16.2M | 1.1x |
| Строка (min/max) | 8.0M | 17.2M | 2.2x |
| Enum | 12.3M | 16.9M | 1.4x |
| Кортеж [string, int, bool] | 6.5M | 17.0M | 2.6x |
| Set<string> (20 эл.) | 695K | 12.1M | 17x |
| Map<string, number> (20 эл.) | 361K | 8.6M | 24x |
| Discriminated union (3 варианта) | 4.0M | 16.1M | 4.0x |
| Объект среднего размера (валидный) | 2.4M | 10.3M | 4.3x |
| Объект среднего размера (невалидный) | 80K | 15.5M | 194x |
| Большой объект (100 полей) | 19K | 1.4M | 73x |
| Глубоко вложенный объект (243 листа) | 19K | 1.2M | 64x |
| Рекурсивное дерево (121 узел) | 142K | 2.3M | 16x |
Наибольший прирост дают вложенные объекты, большие схемы и некорректные данные (где Zod строит дорогие объекты ошибок, а скомпилированный валидатор откладывает материализацию ошибок). Случай с невалидным объектом достигает 194x, потому что быстрый путь отклоняет некорректный ввод одной булевой проверкой — дорогое дерево ошибок никогда не создаётся.
zod-compiler использует двухфазный валидатор:
&&, проверяющая весь ввод с нулевым выделением памяти. Корректный ввод возвращается мгновенно..error.
Дополнительные оптимизации: порядок проверок (сначала дешёвые), предварительно
скомпилированные регулярные выражения, Set-поиск для enum, инлайнинг маленьких enum
(≤5 значений через ===), O(1) switch-диспетчеризация для discriminated
unions и автоопределение обычных z.union размеченных объектов.
.is()
Скомпилированные схемы предоставляют дополнительный метод: .is(input): input is T.
Для большинства схем (объекты, примитивы, массивы, enum без coerce,
default, catch или transform) это самая дешёвая
проверка «совпадает ли?»:
// Вместо safeParse().success:
if (UserSchema.is(data)) {
data.email; // сужение до типа вывода схемы
}
// Фильтрация невалидных элементов:
const valid = items.filter((x) => UserSchema.is(x));
Охранник .is() возвращает булево значение без единого выделения памяти —
никакого SafeParseResult, никакого массива ошибок, никакого дерева.
Он сопоставим с Typia is<T>() и является чистой заменой
schema.safeParse(x).success.
zod-compiler спроектирован для минимального влияния на размер бандла:
email, uuid, ipv4 и т.д. появляются один раз во всём бандле.Address или Money) разделяют общую функцию сбора ошибок.output: "bag" чтобы убрать ссылку на оригинальную схему Zod, если вам не нужен instanceof или .shape.
Скомпилированная схема сохраняет полную совместимость с API Zod.
Оптимизированные методы parse/safeParse/parseAsync/
safeParseAsync устанавливаются непосредственно на исходный объект схемы:
._zod — без изменений.shape — без изменений~standard) — без измененийinstanceof — работает.meta() / z.globalRegistry — работаютz.toJSONSchema() — работаетБиблиотеки, принимающие схемы Zod, работают без изменений:
zodResolver использует скомпилированный .parseВ автоматическом режиме плагин выполняет файлы для проверки экспортов. Если файл схемы имеет побочные эффекты (запускает сервер, подключается к БД), они выполнятся на этапе сборки. zod-compiler защищает от этого:
process.env.ZOD_COMPILER для оповещения модулейprocess.exit — выход превращается в обычную ошибку загрузки, сборка не ломается
Простейший способ избежать проблем — использовать include:
zodCompiler({
include: ["src/schemas", "src/validators"],
});
zod-compiler имеет постоянный кэш трансформаций в node_modules/.cache/zod-compiler.
Записи кэша самопроверяются по хешам содержимого зависимостей — восстановление устаревшего
кэша вызывает перекомпиляцию, но никогда не выдаёт устаревший вывод:
- uses: actions/cache@v4
with:
path: node_modules/.cache/zod-compiler
key: zod-compiler-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
Для больших существующих кодовых баз начните с schemas: "explicit" и
оберните только самые горячие пути — схемы, валидируемые чаще всего или на самых
больших объёмах данных. Валидация API-запросов, проверка строк БД и обработчики форм —
цели с наибольшим эффектом.
zod-compiler — один из тех редких инструментов, который даёт драматический прирост производительности с нулевыми усилиями разработчика. Установите плагин, оставьте все существующие схемы Zod, и ваша валидация станет в 2–75 раз быстрее. Никаких изменений API, никакой миграции, никаких runtime-зависимостей.
Двухфазная архитектура — быстрый путь для корректных данных, ленивая материализация ошибок для невалидных — означает, что типичный случай (большинство данных проходит валидацию) работает так же быстро, как ручной типовой охранник. А функция поднятия схем устраняет целый класс багов производительности, когда схемы пересоздаются при каждом рендере React или каждом вызове обработчика.
Если ваш проект использует Zod — попробуйте zod-compiler. Запустите
pnpm benchmark локально, чтобы увидеть улучшение на вашем железе.
Цифры говорят сами за себя.
Строите приложение, интенсивно работающее с данными, которому нужна эффективная валидация? Могу помочь с архитектурой и реализацией. Бесплатная первичная консультация.