Skip to content

Commit a66e0e6

Browse files
Shuunenjordan-boyer
authored andcommitted
feat: add zod/mini library to the contest
1 parent e53bebd commit a66e0e6

File tree

4 files changed

+94
-17
lines changed

4 files changed

+94
-17
lines changed

README.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,36 +32,42 @@ Here are the library used in this comparison :
3232
- [arktype](https://github.com/arktypeio/arktype) from David Blass
3333
- [valibot](https://github.com/fabian-hiller/valibot) from Fabian Hiller
3434
- [zod](https://github.com/colinhacks/zod) from Colin McDonnell
35+
- [zod/mini](https://github.com/colinhacks/zod) from Colin McDonnell
3536

36-
| Date | Score | Library | Deps | Size | Light | Input | Throw | Safe | Script exec | Lib exec | Fast | Readability |
37-
| ---------- | :---: | :-----: | :---: | :----: | :---: | :---: | :---: | :---: | :---------: | :---------: | :---: | :---------: |
38-
| 2025-04-11 | 1 | arktype | 2 | 140 KB | _0_ | **1** | _0_ | **1** | 406 ms _-1_ | 338 ms _-1_ | _0_ | **1** |
39-
| 2025-04-11 | 7 | valibot | **0** | 5 KB | **1** | **1** | **1** | **1** | 14 ms **1** | 4 ms **1** | **1** | _0_ |
40-
| 2025-04-11 | 6 | zod3 | **0** | 60 KB | _0_ | **1** | **1** | **1** | 25 ms **1** | 14 ms _0_ | **1** | **1** |
41-
| 2025-04-11 | 6 | zod4 | 1 | 49 KB | _0_ | **1** | **1** | **1** | 79 ms **1** | 60 ms _0_ | **1** | **1** |
42-
43-
Test have been updated on 04-11 and it now run in a M3 pro that's why the numbers are smaller now
37+
| Date | Score | Library | Deps | Size | Light | Input | Throw | Safe | Script exec | Lib exec | Fast | Readability |
38+
| ---------- | :---: | :-------: | :---: | :----: | :---: | :---: | :---: | :---: | :----------: | :---------: | :---: | :---------: |
39+
| 2025-04-13 | 0 | arktype | 2 | 147 KB | _0_ | **1** | _0_ | **1** | 873 ms _-1_ | 691 ms _-1_ | _0_ | **1** |
40+
| 2025-04-13 | 7 | valibot | **0** | 5 KB | **1** | **1** | **1** | **1** | 68 ms **1** | 11 ms **1** | **1** | _0_ |
41+
| 2025-04-13 | 7 | zod v3 | **0** | 60 KB | _0_ | **1** | **1** | **1** | 101 ms **1** | 35 ms **1** | **1** | **1** |
42+
| 2025-04-13 | 4 | zod v4 | 1 | 49 KB | _0_ | **1** | **1** | **1** | 222 ms _0_ | 144 ms _0_ | _0_ | **1** |
43+
| 2025-04-13 | 4 | @zod/mini | 1 | 21 KB | **1** | **1** | **1** | **1** | 243 ms _0_ | 168 ms _0_ | _0_ | **1** |
4444

4545
Legend :
4646

4747
- Deps : the number of dependencies of the library
4848
- Size : the minified build size in bytes of the related file in `src`, run `bun run build` to see by yourself
49-
- Light : 1 point if the build is less than 10 KB
49+
- Light : 1 point if the build is `<= 20 KB`
5050
- Input : 1 point if the library can see that `age` is optional in the input but not optional in `type User` the output type
5151
- Throw : 1 point if the library have a parse or throw method, useful when we don't want to handle the error cases
5252
- Safe : 1 point if the library have a safe parse method that will not throw and usually return a `Result` type
53-
- Script exec : 1 point if the average time in milliseconds to execute the test file with bun is under `100ms`, check the `bun run bench` command output
54-
- Lib exec : 1 point if the average time in milliseconds to execute the library is under `30ms`, check the `bun run check:once` command output
53+
- Script exec : 1 point if the average time in ms to execute the test file with bun is `<= 100ms`, check the `bun run bench` command output
54+
- Lib exec : 1 point if the average time in ms to execute the library is `<= 35ms`, check the `bun run check:once` command output
5555
- Fast : 1 point if the library execution time is less than 100 ms
5656
- Readability : 1 point if the library is easy to write & read, the syntax need to be intuitive
5757

58+
Test have been run on :
59+
60+
- Windows 11 x64
61+
- AMD Ryzen 7 7800X3D, 64GB of RAM
62+
- Bun v1.2.4
63+
5864
## My favorite pick
5965

6066
Zod is my favorite pick because it's fast and provide a better readability.
6167

6268
Ok the build size is bigger but it does not impact the performance that much.
6369

64-
The 34ms vs 10ms seems like a 3x difference but it's the time to run 1000 iterations. So in the end it's not that much of a difference in a real world scenario.
70+
The 35ms vs 11ms seems like a 3x difference but it's the time to run 1000 iterations. So in the end it's not that much of a difference in a real world scenario.
6571

6672
For some weird reason zod4 seems to be slower than zod3
6773

@@ -71,7 +77,7 @@ For some weird reason zod4 seems to be slower than zod3
7177
- [ ] check error messages
7278
- [ ] check custom error messages
7379
- [ ] check custom validation rules
74-
- [X] check the perf without using `console`
80+
- [ ] check the perf without using `console`
7581

7682
## How to contribute
7783

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
}
1313
],
1414
"dependencies": {
15+
"@zod/mini": "4.0.0-beta.20250412T085909",
1516
"arktype": "^2.1",
1617
"valibot": "latest",
1718
"zod3": "npm:zod@^3.24.2",
@@ -44,12 +45,12 @@
4445
},
4546
"scripts": {
4647
"bench": "bun bench:bun --warmup 5 --runs 10",
47-
"bench:bun": "hyperfine 'bun src/arktype.ts' 'bun src/valibot.ts' 'bun src/zod3.ts' 'bun src/zod4.ts'",
48-
"bench:node": "hyperfine --runs 10 'node dist/arktype.js' 'node dist/valibot.js' 'node dist/zod3.js' 'node dist/zod4.js'",
49-
"bench:node:strip": "hyperfine --runs 10 'node --experimental-strip-types src/arktype.ts' 'node --experimental-strip-types src/valibot.ts' 'node --experimental-strip-types src/zod3.ts' 'node --experimental-strip-types src/zod4.ts'",
48+
"bench:bun": "hyperfine 'bun src/arktype.ts' 'bun src/valibot.ts' 'bun src/zod3.ts' 'bun src/zod4.ts' 'bun src/zod-mini.ts'",
49+
"bench:node": "hyperfine --runs 10 'node dist/arktype.js' 'node dist/valibot.js' 'node dist/zod3.js' 'node dist/zod4.js' 'node dist/zod-mini.js'",
50+
"bench:node:strip": "hyperfine --runs 10 'node --experimental-strip-types src/arktype.ts' 'node --experimental-strip-types src/valibot.ts' 'node --experimental-strip-types src/zod3.ts' 'node --experimental-strip-types src/zod4.ts' 'node --experimental-strip-types src/zod-mini.ts'",
5051
"build": "bun scripts/build.ts && echo build success",
5152
"check": "pnpm i && bun check:tsc && bun run build && bun check:once && echo check success",
52-
"check:once": "bun src/arktype.ts && bun src/valibot.ts && bun src/zod3.ts && bun src/zod4.ts && echo check:once success",
53+
"check:once": "bun src/arktype.ts && bun src/valibot.ts && bun src/zod3.ts && bun src/zod4.ts && bun src/zod-mini.ts && echo check:once success",
5354
"check:repo": "repo-check && echo check:repo success",
5455
"check:tsc": "tsc --noEmit && echo check:tsc success"
5556
},

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/zod-mini.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {
2+
string,
3+
number,
4+
object,
5+
type infer as InferOutput,
6+
type input as InferInput,
7+
refine,
8+
optional,
9+
_default,
10+
} from "@zod/mini";
11+
import { checkUserA, checkUserB, checkUserC, nbIterations } from "./utils.ts";
12+
13+
const startTime = performance.now();
14+
15+
for (let i = 0; i < nbIterations; i++) {
16+
const userSchema = object({
17+
name: string(),
18+
age: _default(optional(number()), 42),
19+
phone: _default(
20+
optional(
21+
string().check(
22+
refine((phone) => (typeof phone === "number" ? String(phone) : phone))
23+
)
24+
),
25+
"123-456-7890"
26+
),
27+
});
28+
29+
// @ts-expect-error not exported, it's ok :p
30+
type User = InferOutput<typeof userSchema>;
31+
32+
type UserInput = InferInput<typeof userSchema>;
33+
34+
const userA = userSchema.parse({ name: "Jordan", age: 42 });
35+
checkUserA(userA);
36+
37+
function createUser(input: UserInput) {
38+
const result = userSchema.safeParse(input);
39+
if (!result.success) return userA;
40+
return result.data;
41+
}
42+
43+
const userB = createUser({ name: "Romain", age: 35, phone: "1234567890" });
44+
checkUserB(userB);
45+
46+
// @ts-expect-error age should be a number
47+
const userC = createUser({ name: "Romain", age: "35" });
48+
checkUserC(userC);
49+
}
50+
51+
console.log(
52+
`Zod 4 mini exec time for ${nbIterations} iterations :`,
53+
performance.now() - startTime,
54+
"ms"
55+
);

0 commit comments

Comments
 (0)