zod-aot 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -34
- package/package.json +1 -7
- package/dist/internals.d.ts +0 -7
- package/dist/internals.d.ts.map +0 -1
- package/dist/internals.js +0 -4
- package/dist/internals.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,22 +7,22 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/zod-aot)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
|
-
No code changes required — keep your existing Zod schemas and get **2-
|
|
10
|
+
No code changes required — keep your existing Zod schemas and get **2-80x faster** validation.
|
|
11
11
|
|
|
12
12
|
## Why
|
|
13
13
|
|
|
14
14
|
Zod v4 is already fast, but runtime schema traversal still costs ~10x compared to ahead-of-time (AOT) compiled approaches. Existing AOT solutions like [Typia](https://typia.io/) require rewriting your schemas as TypeScript types. **zod-aot** bridges this gap — it takes your existing Zod schemas and generates optimized, plain JavaScript validation functions at build time.
|
|
15
15
|
|
|
16
|
-
| |
|
|
17
|
-
|
|
18
|
-
| **Input** | Zod schemas
|
|
19
|
-
| **Existing code changes** | None
|
|
20
|
-
| **Type inference** | Inherited from Zod
|
|
21
|
-
| **Runtime dependency** | None (generated code) | Typia runtime | AJV runtime | Zod |
|
|
16
|
+
| | Zod AOT | Typia | AJV standalone | Zod v3 | Zod v4 |
|
|
17
|
+
|---|---------------------|---|---|---|---|
|
|
18
|
+
| **Input** | Zod schemas | TS types | JSON Schema | Zod schemas | Zod schemas |
|
|
19
|
+
| **Existing code changes** | None | Full rewrite | Full rewrite | N/A | N/A |
|
|
20
|
+
| **Type inference** | Inherited from Zod | Native | External | Native | Native |
|
|
21
|
+
| **Runtime dependency** | None (generated code) | Typia runtime | AJV runtime | Zod | Zod |
|
|
22
22
|
|
|
23
23
|
## Benchmarks
|
|
24
24
|
|
|
25
|
-
Measured with `vitest bench` on Node.js (Apple M-series). The benchmark suite compares **
|
|
25
|
+
Measured with `vitest bench` on Node.js (Apple M-series). The benchmark suite compares **Zod v3**, **Zod v4**, **zod-aot**, **[ajv](https://ajv.js.org/)**, and **[typia](https://typia.io/)** across primitives, objects, collections, unions, recursive schemas, and real-world scenarios.
|
|
26
26
|
|
|
27
27
|
Run benchmarks locally:
|
|
28
28
|
|
|
@@ -30,27 +30,29 @@ Run benchmarks locally:
|
|
|
30
30
|
pnpm bench
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
### safeParse
|
|
34
|
-
|
|
35
|
-
| Scenario | Zod v4 |
|
|
36
|
-
|
|
37
|
-
| simple string |
|
|
38
|
-
| string (min/max) | 5.
|
|
39
|
-
| number (int+positive) |
|
|
40
|
-
| enum | 9.1M ops/s |
|
|
41
|
-
| tuple [string, int, boolean] | 4.
|
|
42
|
-
| record\<string, number\> (5 keys) | 1.9M ops/s |
|
|
43
|
-
| discriminatedUnion (3 variants) |
|
|
44
|
-
| medium object (7 props, valid) | 1.
|
|
45
|
-
| medium object (7 props, invalid) |
|
|
46
|
-
| large object (10 nested items) |
|
|
47
|
-
| large object (100 nested items) | 11.
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
| partial fallback
|
|
52
|
-
|
|
53
|
-
|
|
33
|
+
### safeParse
|
|
34
|
+
|
|
35
|
+
| Scenario | Zod v3 | Zod v4 | Zod AOT | vs v3 | vs v4 |
|
|
36
|
+
|---|---|---|-----------|---|---|
|
|
37
|
+
| simple string | 8.2M ops/s | 9.6M ops/s | 10.4M ops/s | **1.3x** | **1.1x** |
|
|
38
|
+
| string (min/max) | 7.8M ops/s | 5.4M ops/s | 10.5M ops/s | **1.4x** | **2.0x** |
|
|
39
|
+
| number (int+positive) | 7.8M ops/s | 5.7M ops/s | 10.5M ops/s | **1.3x** | **1.8x** |
|
|
40
|
+
| enum | 7.5M ops/s | 9.1M ops/s | 10.0M ops/s | **1.3x** | **1.1x** |
|
|
41
|
+
| tuple [string, int, boolean] | 4.2M ops/s | 4.6M ops/s | 10.5M ops/s | **2.5x** | **2.3x** |
|
|
42
|
+
| record\<string, number\> (5 keys) | 2.3M ops/s | 1.9M ops/s | 5.6M ops/s | **2.4x** | **2.9x** |
|
|
43
|
+
| discriminatedUnion (3 variants) | 2.3M ops/s | 2.9M ops/s | 9.3M ops/s | **4.1x** | **3.3x** |
|
|
44
|
+
| medium object (7 props, valid) | 1.3M ops/s | 1.7M ops/s | 5.2M ops/s | **4.0x** | **3.0x** |
|
|
45
|
+
| medium object (7 props, invalid) | 346K ops/s | 62K ops/s | 467K ops/s | **1.4x** | **7.5x** |
|
|
46
|
+
| large object (10 nested items) | 83K ops/s | 110K ops/s | 4.0M ops/s | **48x** | **36x** |
|
|
47
|
+
| large object (100 nested items) | 8.5K ops/s | 11.3K ops/s | 680K ops/s | **80x** | **60x** |
|
|
48
|
+
| recursive tree (7 nodes) | 398K ops/s | 1.5M ops/s | 6.3M ops/s | **16x** | **4.2x** |
|
|
49
|
+
| recursive tree (121 nodes) | 23K ops/s | 101K ops/s | 749K ops/s | **33x** | **7.4x** |
|
|
50
|
+
| event log (combined) | 265K ops/s | 440K ops/s | 4.4M ops/s | **17x** | **10x** |
|
|
51
|
+
| partial fallback object (transform) | 822K ops/s | 1.4M ops/s | 3.5M ops/s | **4.2x** | **2.4x** |
|
|
52
|
+
| partial fallback array 10 (transform) | 85K ops/s | 144K ops/s | 1.1M ops/s | **13x** | **7.7x** |
|
|
53
|
+
| partial fallback array 50 (transform) | 18K ops/s | 30K ops/s | 237K ops/s | **13x** | **7.8x** |
|
|
54
|
+
|
|
55
|
+
Performance gains scale with schema complexity. The `discriminatedUnion` optimization uses an O(1) `switch` dispatch instead of Zod's sequential trial approach. Partial fallback schemas (containing `transform`/`refine`) still show 2-8x speedups by compiling the optimizable portions.
|
|
54
56
|
|
|
55
57
|
## Runtime Support
|
|
56
58
|
|
|
@@ -302,7 +304,7 @@ interface CompiledSchema<T> {
|
|
|
302
304
|
|
|
303
305
|
| Type | Supported Checks |
|
|
304
306
|
|---|---|
|
|
305
|
-
| `string` | `min`, `max`, `length`, `email`, `url`, `uuid`, `regex` |
|
|
307
|
+
| `string` | `min`, `max`, `length`, `email`, `url`, `uuid`, `regex`, `includes`, `startsWith`, `endsWith` |
|
|
306
308
|
| `number` | `int`, `positive`, `negative`, `nonnegative`, `nonpositive`, `min`, `max`, `multipleOf` |
|
|
307
309
|
| `bigint` | `min`, `max`, `positive`, `negative`, `nonnegative`, `nonpositive`, `multipleOf` |
|
|
308
310
|
| `boolean` | — |
|
|
@@ -327,6 +329,7 @@ interface CompiledSchema<T> {
|
|
|
327
329
|
| `nullable` | wraps any supported type |
|
|
328
330
|
| `readonly` | validates inner type (TS-only concept) |
|
|
329
331
|
| `default` | replaces `undefined` with default value, then validates inner |
|
|
332
|
+
| `lazy` (self-recursive) | cycle detection → self-recursive codegen |
|
|
330
333
|
|
|
331
334
|
### Automatic Fallback to Zod
|
|
332
335
|
|
|
@@ -336,7 +339,7 @@ These schema types contain JavaScript closures or runtime-dependent logic that c
|
|
|
336
339
|
- `refine` / `superRefine` — custom validation with closures
|
|
337
340
|
- `custom` — arbitrary validation logic
|
|
338
341
|
- `preprocess` — input preprocessing
|
|
339
|
-
- `lazy` — deferred schema resolution
|
|
342
|
+
- `lazy` (non-recursive) — deferred schema resolution where inner type cannot be resolved
|
|
340
343
|
|
|
341
344
|
#### Partial Fallback
|
|
342
345
|
|
|
@@ -353,7 +356,7 @@ pnpm install
|
|
|
353
356
|
# Run tests
|
|
354
357
|
pnpm test
|
|
355
358
|
|
|
356
|
-
# Run benchmarks (zod vs zod-aot vs ajv vs typia)
|
|
359
|
+
# Run benchmarks (zod v3 vs zod v4 vs zod-aot vs ajv vs typia)
|
|
357
360
|
pnpm bench
|
|
358
361
|
|
|
359
362
|
# Lint (Biome)
|
|
@@ -373,7 +376,6 @@ zod-aot/
|
|
|
373
376
|
├── packages/zod-aot/ # Main npm package
|
|
374
377
|
│ ├── src/
|
|
375
378
|
│ │ ├── index.ts # Public API exports (zod-aot)
|
|
376
|
-
│ │ ├── internals.ts # Internal API exports (zod-aot/internals)
|
|
377
379
|
│ │ ├── discovery.ts # Schema discovery (shared by CLI & unplugin)
|
|
378
380
|
│ │ ├── loader.ts # Runtime-aware file loader
|
|
379
381
|
│ │ ├── core/ # Pure logic (no CLI/unplugin deps)
|
|
@@ -385,7 +387,7 @@ zod-aot/
|
|
|
385
387
|
│ │ ├── cli/ # CLI commands (generate, check, watch)
|
|
386
388
|
│ │ └── unplugin/ # Build plugin (Vite/webpack/esbuild/Rollup/Rolldown/Bun)
|
|
387
389
|
│ └── tests/
|
|
388
|
-
├── benchmarks/ # vitest bench (zod vs zod-aot vs ajv vs typia)
|
|
390
|
+
├── benchmarks/ # vitest bench (zod v3 vs v4 vs zod-aot vs ajv vs typia)
|
|
389
391
|
└── .github/workflows/ # CI + release automation
|
|
390
392
|
```
|
|
391
393
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod-aot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Compile Zod schemas into zero-overhead validation functions at build time",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -74,12 +74,6 @@
|
|
|
74
74
|
"source": "./src/unplugin/bun.ts",
|
|
75
75
|
"import": "./dist/unplugin/bun.js",
|
|
76
76
|
"default": "./dist/unplugin/bun.js"
|
|
77
|
-
},
|
|
78
|
-
"./internals": {
|
|
79
|
-
"types": "./dist/internals.d.ts",
|
|
80
|
-
"source": "./src/internals.ts",
|
|
81
|
-
"import": "./dist/internals.js",
|
|
82
|
-
"default": "./dist/internals.js"
|
|
83
77
|
}
|
|
84
78
|
},
|
|
85
79
|
"dependencies": {
|
package/dist/internals.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export type { CodeGenResult } from "#src/core/codegen/index.js";
|
|
2
|
-
export { generateValidator } from "#src/core/codegen/index.js";
|
|
3
|
-
export type { FallbackEntry } from "#src/core/extract/index.js";
|
|
4
|
-
export { extractSchema } from "#src/core/extract/index.js";
|
|
5
|
-
export { createFallback } from "#src/core/runtime.js";
|
|
6
|
-
export type { CheckIR, DateCheckIR, SchemaIR } from "#src/core/types.js";
|
|
7
|
-
//# sourceMappingURL=internals.d.ts.map
|
package/dist/internals.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/internals.js
DELETED
package/dist/internals.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"internals.js","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|