- Unified Object Behaviour – .passthrough()replaces.nonstrict()and better aligns with Zod’s philosophy of explicitness.
- Enhanced Metadata APIs – meta()supersedes several ad-hoc helpers such as.describe().
- Error Handling Revamp – new ZodErrorexport path and richer error objects.
- Union & Intersection Updates – explicit helpers (z.union,z.intersection) over chained.or()/.and()calls.
- Ecosystem Clean-up – deprecated utilities removed, smaller bundle size, faster parse times.
Getting started
Migration Steps
1
Install Zod 4
Install the latest major version of Zod. We recommend using exact versions to avoid surprises:Zod has no peer dependencies, so that’s the only package you need to bump.
2
Run the codemod
Launch the codemod recipe to automatically rewrite common breaking changes:View a list of available CLI commands & options here ->
Can you rollback?Git is your friend—commit before you run the codemod. The Codemod CLI also supports the 
--dry-run flag which lets you preview the changes without applying them.What the recipe changes
The migration recipe only targets Zod-specific breaking changes. It will not touch unrelated code patterns likevar declarations or debug console.log statements. Concretely, it performs the following refactors:- .nonstrict()→- .passthrough()
- Chained .or()/.and()calls →z.union([...])/z.intersection([...])
- .describe("…")→- .meta({ description: "…" })
- Updates ZodError,z.ZodSchemaimport paths to the newzod/v4entrypoints
- Removes helpers removed in v4 (z.lazyobject, legacy refinements, etc.)
3
Review & test
The codemod handles most changes, but some APIs require manual tweaks. We recommend:
- Type-check the project:
- Run your test suite and fix any remaining failures.
- Search for TODO(zod-4-migration)comments the codemod leaves behind for ambiguous cases.
4
Before & After examples
Below is a non-exhaustive diff generated by the codemod:
diff
Tested versions
| From | To | Languages | 
|---|---|---|
| zod@3.22.x | zod@4.0.0 | JavaScript & TypeScript | 
FAQ
Does the codemod cover every breaking change?
No. It focuses on the highest-impact, mechanical updates. Review the Zod release notes for edge-cases such as custom.refine() logic or plugin APIs.