As a convenience and mostly avoid typos in form names I use my own version of https://github.com/raflymln/zod-key-parser. I've been surprised something like this hasn't been implemented directly in the library.
Curious if you think this is out of scope for Zod or just something you haven't gotten around to implement?
(Here are discussions around it: https://github.com/colinhacks/zod/discussions/2134)
I like your library! Put in a PR to add it to the ecosystem page :)
To be clear: this isn't my library. This is just something I found while trying to solve the FormData issue. Props go to https://github.com/raflymln who created it.
Everyone old in Python ecosystem remembers the Python 2/3 migration madness.
Does this not sound insane?
---
I've been using the alpha versions of Zod for months, I just want to edit package.json and upgrade. But now I need to shotgun across git history instead.
Colin, I appreciate your project immensely. As a point of feedback, you made this ^ much harder than you had to. (Perhaps publish a 4.x along with the 3.x stuff?)
> Perhaps publish a 4.x along with the 3.x stuff
You have some misconceptions about how npm works. Unfortunately it's less reasonable than you think. There's a single `latest` tag, and there's only one "latest" version at a time. It's expected that successive versions here will follow semver. Once I publish zod@4 I can no longer publish additional [email protected] versions. The workaround here is to publish v3 versions to a separate dist tag (zod@three) but anyone consuming that dist-tag (e.g. "zod": "three" in their package.json) loses the ability to specify a semver range.
I recommend reading the writeup[0]. I don't think you're appreciating the magnitude of the disruption a simple major version bump would have caused, or the reasons why this approach is necessary to unlock continuity for Zod's ecosystem libraries. They're quite subtle.
Speaking bluntly, this isn’t how libraries in the npm upgrade, and pitching this does not inspire confidence.
That being said, I'm fully understanding of the reasons for the somewhat odd versioning given your special situation, but still, I'd wish there would be a 4.0.0-package for folks like us who simply don't need to worry or bother about zod-version-clashes in transitive dependencies bacause those don't exist (or at least I think so; npm ls zod only returns our own dependency of zod). If I understood correctly, we'll need to adapt the import to "zod/v4", which will be an incredibly noisy change and will probably cause quite a few headaches when IDEs auto-import from 'zod' and such, which we then need to catch with linting-rules.
But that's probably a small gripe for a what sounds overall like a very promising upgrade - many thanks for your work once again!
Is fixing .optional() in TS[0] part of the 9/10 top-issues fixed? This has been my biggest pain point with Zod... but still Zod is so good I still choose to just deal with it :) Thanks for an amazing part of the ecosystem.
Now, that's effectively what 3.25 is. But there are some problematic extras... the semantics of the semantic versioning is muddled. That means confusion, which means some people will spin their wheels after not initially grokking the situation correctly. Also, there seems to be an implication there could be a strong deprecation of v3 APIs coming. That is, you have to wonder how long the window for incremental migration will remain open.
To be frank, I wouldn't touch zod on any project I hoped will be around for a while. Predicting the future is an uncertain business, but we can look at the past. In a few years, I think it's reasonable to guess zod v4 will be getting the same treatment zod v3 is getting now.
Not that I think you ought to do anything different. I probably wouldn't want to maintain some old API I came up with years ago indefinitely either (not without a decent support contract, that is).
https://github.com/mary-ext/atcute/blob/596e023bcb490b16d09a...
Breaking changed in fundamental but auxiliary libraries are so painful in the world of frontend development that it's not even funny anymore.
This is extremely sensible. And it means you can provide security updates for older versions, just all in the same codebase's releases.
But I am looking forward to seeing if this fixes our issue where in the worst case a 500 line schema file turns into 800,000 lines of generated types.
Report back about that .d.ts issue. It should be far better. That kind of type explosion usually happens when TypeScript needs to infer function/method return types. Zod 4 uses isolatedDeclarations so this kind of thing shouldn't happen.
Regarding the versioning: I wrote a fairly detailed writeup here[0] for those who are interested in the reasons for this approach.
Ultimately npm is not designed to handle the situation Zod finds itself in. Zod is subject to a bunch of constraints that virtually no other libraries are subject to. Namely, the are dozens or hundreds of libraries that directly import interfaces/classes from Zod and use them in their own public-facing API.
Since these libraries are directly coupled to Zod, they would need to publish a new major version whenever Zod does. That's ultimately reasonable in isolation, but in Zod's case it would trigger a "version avalanche" would just be painful for everyone involved. Selfishly, I suspect it would result in a huge swath of the ecosystem pinning on v3 forever.
The approach I ended up using is analogous to what Golang does. In essence a given package never publishes new breaking versions: they just add a new subpath when a new breaking release is made. In the TypeScript ecosystem, this means libraries can configure a single peer dependency on zod@^3.25.0 and support both versions simultaneously by importing what they need from "zod/v3" and "zod/v4". It provides a nice opt-in incremental upgrade path for end-users of Zod too.
[0] https://github.com/colinhacks/zod/issues/4371