By @Nicolas, October 22, 2025
<aside>
ℹ️
This document was publicly shared here: https://github.com/get-convex/convex-helpers/pull/818
</aside>
TL;DR
This is a proposal on how to update our Convex + Zod integration in helpers to support Zod 4 and Zod Codecs.
Why is it useful to have a Convex + Zod integration?
There’s three reasons why our users might want to convert Zod validators to/from Convex validators:
- Convex functions: developers might want to use Zod validators instead of Convex validators to define
args/returns validators.
- ✅ Zod allows for more advanced validation than Convex validators (e.g.
z.string.email())
- ✅ Zod allows for transformations, which can be useful (e.g. convert a value from string to date when received on the server)
- 🎁 We provide functions in helpers (
zCustomQuery/zCustomMutation/zCustomAction) that allows users to get APIs similar to query/mutation/action but with Zod validators.
- ℹ️ Why do we need to generate a similar Convex schema? In theory we could type arguments/return values as
v.any() from the Convex point of view, and perform Zod validation in userspace. Instead, we generate Convex validators that are as close as possible to the Zod types (but possibly broader, e.g. z.string().email() → v.string()), so that users still benefit from Convex-specific features (show the correct UI for the data type in the dashboard, generate correct codegen (for static codegen types, OpenAPI types, other languages…)
- Also, we use Convex validators to validate
v.id() for real (the validation in Zod can’t check the table ID)
- Convex database: instead of using Convex validators to define a table schema, developers might want to use Zod validators.
- ✅ They can use more advanced validation rules
- 🚨🚨🚨 Unlike Convex validators, Zod validators are only run when users read and write through their custom database wrappers. This means that data at rest might get modified in a way that doesn't match the Zod validator.
- ✅ They can use transformations to encode non-compatible data types
- (but without Zod schemas, they would need to have two schemas for each direction 😔)
- 🚫🎁 We don't provide Zod database wrapper in helpers since using Zod for validation isn't fully safe.
- We suggest in Stack articles / helper docs that people write their own wrappers. Whether they validate the data when they read it depends on the use case (what should they do if they read invalid data? do they want to crash or ignore the problem?)
- ℹ️ We also generate the most specific Convex types we can, while being as broad as the zod version, so that users get as much real validation as they can.
- Converting Convex validators to Zod validators in server functions: more rarely used, but can be helpful to use Convex validators with libraries that expect Zod validators, e.g. use Convex validators with the AI SDK
- This is used rarely because Zod validators are more powerful. Often, you’d want to use a feature available in Zod validators but not in Convex validators (e.g. field descriptions for the AI SDK)
Goals
- Support Zod 4
- Continue supporting Zod 3
- https://zod.dev/library-authors strongly recommends that library authors add a peer dependency to
"zod": "^3.25.0 || ^4.0.0", where zod@^3.25.0 contains both code for Zod 3 and Zod 4.
- The same page recommends that library authors support both Zod 3 and Zod 4 for a while to smooth the transition process.
- Offer a great support story for Zod Codecs
- This is helpful for users to overcome limitations of Convex values (e.g. lack of
v.date())
Support Zod 4
The first step will be to start supporting Zod 4 alongside with Zod 3, without any significant API changes. More precisely:
- The peer dependency on
zod will be updated to "zod": "^3.25.0 || ^4.0.0"
- The existing API will be reimplemented for Zod 4 Core in
convex-helpers/zod4
- By API, I mean all of the exported items, i.e.:
- Types
ConvexToZod, ConvexValidatorFromZodOutput, CustomBuilder, ZCustomCtx, ZodValidator, ZodValidatorFromConvex
- Functions
withSystemFields, zid, convexToZod, convexToZodFields, zBrand, zCustomAction, zCustomMutation, zCustomQuery, zodOutputToConvex, zodOutputToConvexFields, zodToConvex, zodToConvexFields
- Classes
Zid, ZodBrandedInputAndOutput
- Zod 4 Core = the core set of APIs working with both Zod 4 Classic and Zod 4 Mini. Zod strongly recommends library authors to work with Zod 4 Core so that both are supported.
- The existing Zod 3 API implementation will be moved to
convex-helpers/zod3