json-schema-to-zod icon indicating copy to clipboard operation
json-schema-to-zod copied to clipboard

Support for Zod 4 (now in beta)

Open colinhacks opened this issue 7 months ago • 7 comments

I'm posting this issue to all the libraries currently listed in the Ecosystem section of Zod's README. Apologies for the spam! Zod 4 is a big release and it's important to get as much of the ecosystem migrated as possible! 👍

Zod 4 is now in beta

Hello! Colin here, creator of Zod. Thank you for contributing this package to the Zod ecosystem!

FYI, the first beta of Zod 4 has been released. It will be in beta for 4 weeks to allow time for ecosystem libraries (such as yours) to implement support before the first stable version is released. The first stable release will be in mid-May. Keep an eye on this PR to track progress: https://github.com/colinhacks/zod/pull/4074

Announcement post: https://v4.zod.dev/v4 Migration guide: https://v4.zod.dev/v4/changelog

⚠️ Note — To avoid confusion and outdated information, the Ecosystem page for Zod 4 is starting from scratch. You'll need to implement support for Zod 4 (guidance below). Once you've done that, submit a PR adding yourself to this file: https://github.com/colinhacks/zod/blob/v4/packages/docs/components/ecosystem.tsx

Migration

There have been some significant changes.

  • A new library @zod/mini has been released with a treeshakable/functional API that mirrors Zod's
  • To facilitate code sharing between zod and @zod/mini, they both have a dependency on a new common core library @zod/core.
  • This new package implements the schema subclasses that are then extended by zod and @zod/mini (and potentially future libraries). It makes it easy to support all these libraries simultaneously, with just one peerDependency on your end. There is little reason for any framework/library to depend directly on zod anymore.
pnpm install @zod/core@^0.0.1

This page is intended as a jumping-off point with some guidance for library authors: @zod/core docs

Don't hesitate to reach out for help/guidance!

  • Post to the #zod4 channel on the Discord
  • Open an issue/discussion on the repo
  • DM me on Discord or X

colinhacks avatar Apr 18 '25 04:04 colinhacks

@StefanTerdell, I'd be happy to contribute to this migration if you require any help as this package is used extensively in my organization. On an initial go-over, the number of changes required do not seem to be too many, mostly changes to the parser, if that.

agarwalvaibhav0211 avatar Apr 19 '25 05:04 agarwalvaibhav0211

cc @StefanTerdell Here's a dedicated guide for library authors that answers some common questions: https://v4.zod.dev/library-authors

  1. Best practices around peer dependencies
  2. How to support Zod v3 and Zod v4 simultaneously
  3. How to support Zod & Zod Mini without extra work

Note that the @zod/core package has been abandoned in favor of a subpath: zod/v4/core. This makes it much easier for libraries with build on top of Zod with a single peer dependency on "zod". The reasons for this change are explained in more detail in the beta announcement: https://v4.zod.dev/v4

colinhacks avatar May 14 '25 23:05 colinhacks

@StefanTerdell Zod 4 just got stable: https://zod.dev/v4, any plans to work on this in the near future? In particular:

  • adding support for recursive schemas
  • use the tree-shakable API - i.e. zod mini ?

lengors avatar May 19 '25 23:05 lengors

Perhaps a simple first step would be to add an option for importing from "zod/v4" instead of from "zod" in the exported type string

adrianlyjak avatar May 27 '25 13:05 adrianlyjak

Hello, will there be an update in the near future or would you rather look for another solution?

abanobboles avatar May 31 '25 14:05 abanobboles

Perhaps a simple first step would be to add an option for importing from "zod/v4" instead of from "zod" in the exported type string

A few more changes are required. For example, z.record now expects at least two arguments.

Here's a simple workaround:

let result = jsonSchemaToZod(jsonSchema, { module: 'esm' });
result = result.replace(/(['"])zod(['"])/g, '$1zod/v4$2');
result = result.replace(/\.record\(/g, '.record(z.string(),');

brunolemos avatar Jun 16 '25 15:06 brunolemos

Hello, I wanted to ask if there has been any advance in this front? Also, I believe that the code below also needs to be changed for zod/v4 compatibility aside from the changes by @brunolemos

ctx.addIssue({
              path: ctx.path,
              code: 'invalid_union',
              unionErrors: errors,
              message: 'Invalid input: Should pass single schema',
            });

To me it works by doing:

jq '{type:"object",properties:.components.schemas,required:(.components.schemas|keys),additionalProperties:false}' generated-schemas/bid-data.json \
  | npx json-schema-to-zod --name BidDataSchemas --stdout \
  | sed -E \
      -e '1s|"zod"|"zod/v4"|' \
      -e 's/\.record\(/.record(z.string(),/g' \
      -e '/if \(schemas\.length - errors\.length !== 1\) {/,/^[[:space:]]*}[[:space:]]*$/d' \
  > web-app/frontend/src/generated/zod/bid-data-schemas.zod.ts

Thanks

danielArchlet avatar Jul 03 '25 06:07 danielArchlet