Capítulo 61 de 61
Zod 4 was rolled out via a subpath-versioning scheme (borrowed from Go's approach to major version changes) specifically so the ecosystem of libraries built on Zod could adopt it incrementally, without every dependent library needing to publish a breaking major version simultaneously.
"zod/v4" subpath alongside zod@3.25.x (with the package root "zod" still exporting Zod 3), letting libraries opt in early without forcing a peer-dependency major bump on their users. Once ecosystem support was broad enough, zod@4.0.0 was published to npm and the package root switched to exporting Zod 4."zod/v3" and "zod/v4" (and "zod/v4-mini"/"zod/mini") remain available indefinitely regardless of what the bare "zod" root currently points to — code importing from a specific subpath keeps working across future major version flips."zod" now means Zod 4 (previously "zod/v4"), "zod/mini" means Zod 4 Mini (previously "zod/v4-mini"), and Zod 3 moved to "zod/v3" (previously the bare "zod" root). Existing "zod/v4"/"zod/v4-mini" imports still work.zod@4.0.0 directly: peer-dependency mechanics can't cleanly express "supports either major version" across package managers — dual-installing via npm aliases breaks instanceof checks between copies, a wide peer range still forces picking one version to develop/test against, optional peer dependencies have no reliable cross-platform runtime detection (especially in frontend bundlers), and hand-written compatibility-shim packages are error-prone and runtime-code-blind. Subpath versioning sidesteps all of these by letting a single "zod" peer dependency range cover both major versions, with libraries importing explicitly from "zod/v3"/"zod/v4" internally."^3.25.0 || ^4.0.0" and import from the version-specific subpaths internally — no other code changes were required moving from 3.25.x to 4.0.0, since that transition itself introduced no breaking changes.// package.json — supporting both Zod 3 and Zod 4 as a library author
{
"peerDependencies": {
"zod": "^3.25.0 || ^4.0.0"
}
}
// referencing both versions explicitly and permanently
import * as z3 from "zod/v3";
import * as z4 from "zod/v4/core";
"zod/v3", "zod/v4"/"zod/v4/core") rather than the bare "zod" root, so your code keeps working regardless of what the root currently points to.