Skip to content

feat: update to zod v4 #1038

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jul 29, 2025
Merged

feat: update to zod v4 #1038

merged 21 commits into from
Jul 29, 2025

Conversation

matejchalk
Copy link
Collaborator

@matejchalk matejchalk commented Jul 28, 2025

Updates to Zod 4. This required several changes to our Zod code (see full migration guide if interested):

  • Descriptions in options parameter (e.g. z.string({ description: '...' }) or z.object(..., { description: '...' })) are no longer supported, requires additional method call. Used schema.describe('...') (syntax sugar for schema.meta({ description: '...' }), which is itself syntax sugar for z.globalRegistry.add(schema, { description: '...' }) - see metadata in Zod 4).
  • The second parameter for refine has been dropped, i.e. .refine(validatorFn, messageFn) no longer works. Seems that error messages can only be set statically via .refine, so I refactored these validations to use the more flexible .check(ctx => ...) method. To reduce verbosity, I've created some helper functions that serve our purposes (see checks.ts and checks.unit.test.ts).
  • There was a major breaking change to z.function - it no longer returns a Zod schema, but a function factory. I created a helper function to convert it to a schema, and added metadata so zod2md can recognize the function signature (see function.ts and function.unit.test.ts).
  • Contents of Zod errors have changed, had to update a few test assertions.
  • Replaced zod-validation-error package with new prettifyError function provided by zod.
  • Recursive schemas can be implemented with getters, which removes need for z.lazy for our tree schemas. I had to keep the type annotations in the end, as inferring children type only worked correctly in VSCode, but tsc in our build inferred Record<string, unknown>, leading to build errors in utils and core.
  • For z.record, both key and value schemas are now required (keys were implicitly z.string() in v3). Also, enum keys are now exhaustive to match TypeScript behaviour, so z.partialRecord is used where keys are supposed to be optional.

Also updated zod2md, were I recently added support for zod@4.

A few of the Zod methods we're using are now deprecated in v4. I'll refactor those in a follow-up PR.

@matejchalk matejchalk self-assigned this Jul 28, 2025
@matejchalk matejchalk changed the title Zod v4 feat: update to zod v4 Jul 28, 2025
Copy link

Code PushUp

🤨 Code PushUp report has both improvements and regressions – compared current commit cbd31d7 with previous commit ed01057.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Categories

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Security 🔴 44 🔴 0 ↓ −43.8
Performance 🔴 43 🔴 47 ↑ +4.1
Updates 🟡 74 🟡 77 ↑ +2.6
Code coverage 🟢 90 🟢 90 ↓ −0.2
Documentation 🔴 23 🔴 23 ↑ +0.1
Accessibility 🟢 92 🟢 92
Best Practices 🟢 100 🟢 100
SEO 🟡 61 🟡 61
Type Safety 🟢 100 🟢 100
Bug prevention 🟢 100 🟢 100
Miscellaneous 🟢 100 🟢 100
Code style 🟢 100 🟢 100
👍 3 groups improved, 👎 2 groups regressed, 👍 4 audits improved, 👎 6 audits regressed, 14 audits changed without impacting score

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
JS Packages NPM audit 🔴 44 🔴 0 ↓ −43.8
Lighthouse Performance 🔴 43 🔴 47 ↑ +4.1
JS Packages NPM outdated dependencies 🟡 74 🟡 77 ↑ +2.6
Code coverage Code coverage metrics 🟢 90 🟢 90 ↓ −0.2
JSDoc coverage Documentation coverage 🔴 23 🔴 23 ↑ +0.1

16 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
JS Packages Vulnerabilities for NPM prod dependencies. 🟨 8 vulnerabilities (4 high, 4 low) 🟥 9 vulnerabilities (1 critical, 2 high, 6 low) ↑ +12.5 %
Lighthouse Largest Contentful Paint 🟥 4.4 s 🟨 3.7 s ↓ −16.3 %
JS Packages Outdated NPM prod dependencies. 🟨 17 outdated package versions (6 major, 7 minor, 4 patch) 🟨 17 outdated package versions (5 major, 6 minor, 6 patch)  +0 %
Lighthouse First Contentful Paint 🟥 3.1 s 🟥 3.2 s ↑ +2.5 %
Lighthouse Time to Interactive 🟥 14.2 s 🟥 16.0 s ↑ +12.4 %
Lighthouse Speed Index 🟥 6.7 s 🟥 6.9 s ↑ +3.2 %
JSDoc coverage Functions coverage 🟥 496 undocumented functions 🟥 483 undocumented functions ↓ −2.6 %
Code coverage Function coverage 🟩 93.3 % 🟩 93.1 % ↓ −0.2 %
Code coverage Branch coverage 🟨 85.9 % 🟨 85.8 % ↓ −0.1 %
JSDoc coverage Types coverage 🟥 230 undocumented types 🟥 229 undocumented types ↓ −0.4 %
Lighthouse Avoids enormous network payloads 🟩 Total size was 2,031 KiB 🟩 Total size was 1,997 KiB ↓ −1.7 %
Lighthouse Metrics 🟩 100% 🟩 100% ↑ +12.4 %
Lighthouse JavaScript execution time 🟥 7.0 s 🟥 8.7 s ↑ +24.4 %
Lighthouse Server Backend Latencies 🟩 1,550 ms 🟩 190 ms ↓ −88.1 %
Lighthouse Minimizes main-thread work 🟥 18.3 s 🟥 17.4 s ↓ −5.1 %
Lighthouse Total Blocking Time 🟥 4,050 ms 🟥 4,340 ms ↑ +7.3 %
Lighthouse Max Potential First Input Delay 🟥 1,830 ms 🟥 2,020 ms ↑ +10.7 %
Lighthouse Uses efficient cache policy on static assets 🟨 31 resources found 🟨 31 resources found ↑ +0.1 %
Lighthouse Initial server response time was short 🟩 Root document took 400 ms 🟩 Root document took 420 ms ↑ +4 %
Lighthouse Network Round Trip Times 🟩 30 ms 🟩 20 ms ↓ −20.2 %
Lighthouse Avoids an excessive DOM size 🟥 2,271 elements 🟥 2,266 elements ↓ −0.2 %
JS Packages Vulnerabilities for NPM dev dependencies. 🟥 31 vulnerabilities (8 critical, 9 high, 10 moderate, 4 low) 🟥 30 vulnerabilities (8 critical, 9 high, 9 moderate, 4 low) ↓ −3.2 %
JS Packages Outdated NPM dev dependencies. 🟨 56 outdated package versions (29 major, 23 minor, 4 patch) 🟨 55 outdated package versions (29 major, 22 minor, 4 patch) ↓ −1.8 %
Code coverage Line coverage 🟨 86.8 % 🟨 86.8 % ↑ +0.1 %

581 other audits are unchanged.

@matejchalk matejchalk marked this pull request as ready for review July 29, 2025 06:23
@matejchalk matejchalk requested a review from BioPhoton as a code owner July 29, 2025 06:23
@matejchalk matejchalk requested review from vmasek and hanna-skryl July 29, 2025 06:23
@matejchalk matejchalk added the 📚 Code documentation Code related documentation label Jul 29, 2025
@vmasek
Copy link
Collaborator

vmasek commented Jul 29, 2025

Thanks for this refactor, I was looking forward to it since the Zod 4 announcement 🚀

@matejchalk matejchalk merged commit 25ad63e into main Jul 29, 2025
16 of 17 checks passed
@matejchalk matejchalk deleted the zod-v4 branch July 29, 2025 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants