Publish a new [email protected] version which includes [email protected]
The issue
All libraries in the ecosystem have not yet successfully migrated to Zod 4. Those libraries especially:
-
@modelcontextprotocol/sdk -
openai
Are still expecting Zod 3. My issue is that I'm working in a monorepo which uses zod-openapi and I'd like to migrate all my codebase to Zod 4 in the long run.
But the fact that the two above libraries still expect Zod 3 prevents me of updating to [email protected], which in turn prevents me from moving to the version of zod-openapi that supports Zod 4. This version indeed rely on the fact that openapi-3.0 exist as version from the toJsonSchema method. But this target has been introduced in [email protected].
So I'm either stuck on Zod 3 until the two above libs fully embrace Zod 4 or if there could exist a new Zod 3 version that includes [email protected].
The solution
Maybe a good idea to smooth migration for people waiting on third party libs would be to periodically publish a [email protected] version that includes the latest [email protected] update?
You do not need a new [email protected] release that bundles [email protected] to support migration. Starting from [email protected], both Zod 3 and Zod 4 are included in the package at dedicated subpaths. This means you can reference Zod 3 and Zod 4 side-by-side using subpath imports:
import * as z3 from "zod/v3";
import * as z4 from "zod/v4";
This approach allows libraries and applications to support both versions simultaneously in a monorepo or migration scenario. Libraries should depend on "zod" with a peer dependency of ^3.25.0 or higher, which provides access to both versions. There is no need for a special [email protected] release that includes newer [email protected] updates—this setup is already supported for incremental migration(1), (2).
📚 Sources:
Have another question? Just tag @inkeep.
@inkeep this is not enough, because the third party libs mentionned above still have their exports as from 'zod' internally and have not updated their package.json to show they both support ^3.25.74 || ^4.0.0.
Moreover, this is not only a package version issue, there can be real code impact.
For example, the openai package has a method called zodResponseFormat which internally is typed with imports from 'zod', which in the point of view of the lib is either zod@3 or zod@4 depending on the parent project Zod version. But the package really only works with Zod 3 because for example it uses zod-to-json-schema internally, which also doesn't support Zod 4.
So I end up in a situation where either:
- My parent project is on Zod 3.25 and this part works but I lack the functionalities I need from Zod 4.1
- Or my parent project is on Zod 4 and then the typing from
zodResponseFormatmakes me pass a Zod 4 schema (a Zod 3 schema would trigger a type error) but at least I have the functionnalities I need from Zod 4.1
The openai is just one among many examples, I've encountered the same kind of issues with @modelcontextprotocol/sdk, etc.
You are correct that some third-party libraries have not updated their peerDependencies or internal code to support Zod 4, and this can lead to real compatibility and typing issues when migrating in a monorepo or mixed-version environment. The Zod documentation explains that the subpath versioning approach—using [email protected] with both zod/v3 and zod/v4 exports—was designed to allow incremental migration, but it depends on libraries explicitly supporting both versions in their peerDependencies and imports(1).
If a library imports from 'zod' (the package root), it will get Zod 3 until the package root switches over to Zod 4 (which happens after broad ecosystem support). If a library hardcodes Zod 3 types or uses plugins/tools (like zod-to-json-schema) that are not Zod 4 compatible, you will encounter the issues you described(1). There is no supported mechanism in Zod for a [email protected] release to bundle or proxy Zod 4 APIs in a way that would transparently resolve these version and type mismatches(1).
For now, the only migration path described in the documentation is for libraries to update their peerDependencies to allow both ^3.25.0 and ^4.0.0 and to import from the correct subpath. Until those libraries update, you may need to wait or contribute PRs upstream to help them support Zod 4(1).
📚 Sources:
Have another question? Just tag @inkeep.
For now, the only migration path described in the documentation is for libraries to update their peerDependencies to allow both ^3.25.0 and ^4.0.0 and to import from the correct subpath. Until those libraries update, you may need to wait or contribute PRs upstream to help them support Zod 4(1).
Yes, this is the exact reason I'm opening this ticket. Waiting for lib authors can take months, meanwhile my project will continue to rely on Zod 3 because I can't migrate easily. All I'm missing to move to Zod 4 is the openapi-3.0 target in toJsonSchema which is in v4.1 but will break the default import from those libraries.
+1 to @mmorainville-fountain's request here. I was just reading about the great new features in v4.1, but because we're stuck w/ 3.0 in our codebase, we can't yet use 4.1. Would love to have it "backported" to the 3.x release!
I'm also interested in this because of this PR specifically: #5121
Here is the issue I'm encountering is that $ZodTypeDef.type had 'function' added to the union in 4.1. This won't cause a runtime error but it does make following the package author recommendations a little frustrating without messing around with package-lock files (at least in my experience)
@dosu
I'm Dosu, a bot trained on Zod's codebase and issues.
There are no plans to backport Zod 4.1 features (like the openapi-3.0 target in toJsonSchema or changes to $ZodTypeDef.type) to Zod 3.x. Zod 3 is now in maintenance mode and will only receive bug fixes, not new features from Zod 4. The maintainers have stated this explicitly in several issues and discussions—breaking changes and new features are only landing in Zod 4, not in Zod 3.x releases (source, source).
The subpath versioning approach (zod/v3, zod/v4) was chosen to allow incremental migration and avoid a "version bump avalanche" across the ecosystem. This means libraries and apps can support both versions side-by-side, but it does require ecosystem libraries to update their peerDependencies and imports (source, source). There is no mechanism to "bundle" Zod 4 features into the Zod 3 export path—each version is strictly separated in the package (source).
If you're blocked by ecosystem lag, the only supported migration path is to wait for upstream libraries to update, contribute PRs, or use workarounds like exposing only inferred types (not schema instances) in public APIs to sidestep assignability issues (source). For OpenAPI 3.0 compatibility, you can use the override callback in z.toJSONSchema() to post-process schemas, but the openapi-3.0 target itself is only available in Zod 4.1+ (source).
If this answers your question, please feel free to close the issue. If you have more questions or need migration tips, let me know!
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
@dosu is the implication here that if we want to use features from [email protected]+ internally to our library, and to support user-provided schemas, the only option is to drop zod@3 support?
From Dosu chat:
Supporting both Zod 3 and Zod 4 in a single API surface is technically possible with versioned subpath imports and runtime checks, but in practice, TypeScript's type system can't handle the complexity when you try to use Zod 4.1+ features like
toJSONSchemaon a union of v3 and v4 schemas [source]. There is no official workaround that allows you to use these features internally while accepting both versions in your public API without risking this error.