Skip to content

feat: support Zod 4 #777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 7, 2025
Merged

Conversation

colinhacks
Copy link
Contributor

@colinhacks colinhacks commented Jun 5, 2025

Per some discussions I've been having with @bluebill1049, this PR adds support for Zod 4.

The other PR by @alexcraviotto (#776) is really solid but we decided to go another direction.

  • This PR bumps the minimum Zod version to 3.25.0
  • With this change, it;s possible to support both Zod 3 and Zod 4 in a single zodResolver (via Zod's subpath versioning scheme)
  • I've designed this to continue working with Zod versions pre-3.25.0, but it's on a best-effort basis. For instance, you won't get perfect type signatures on parse params (the second argument to zodResolver). There were zero breaking changes between Zod 3.24 and Zod 3.25 so there's no reason not to upgrade.

Both Zod 3 and Zod 4 schemas can be passed into zodResolver():

import { zodResolver } from "@hookform/resolvers";
import * as z3 from "zod/v3"; // or just "zod"
import * as z4 from "zod/v4";

const oldResolver = zodResolver(z3.object({ name: z.string() }));
const newResolver = zodResolver(z4.object({ name: z.string() }));

@colinhacks colinhacks changed the title feat/zod 4 Add Zod 4 support Jun 5, 2025
@colinhacks colinhacks changed the title Add Zod 4 support Support Zod 4 Jun 5, 2025
Copy link
Member

@bluebill1049 bluebill1049 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bluebill1049 bluebill1049 changed the title Support Zod 4 feat: support Zod 4 Jun 5, 2025
Copy link
Member

@jorisre jorisre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the black TypeScript magic 🧙‍♂️ Really appreciate you jumping in and helping out with this. Everything looks solid and comes with a good DX too 🙌

@jorisre jorisre merged commit 8d083bd into react-hook-form:master Jun 7, 2025
4 checks passed
@jorisre jorisre mentioned this pull request Jun 7, 2025
Copy link
Contributor

github-actions bot commented Jun 7, 2025

🎉 This PR is included in version 5.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@alexcraviotto
Copy link

Amazing!

@lucadenardi-sinesy
Copy link

Hello, I'm trying to use react-hook-form with zod/v4.
It seems to me that this code should work, yet I'm facing an issue about incompatible types between the one expected by zodResolver and the passed schema.

//"react-hook-form": "^7.57.0",
import { useForm } from "react-hook-form";

//"@hookform/resolvers": "^5.1.0",
import { zodResolver } from "@hookform/resolvers/zod";

//"zod": "^3.25.57",
import { z } from "zod/v4";

const loginSchema = z.object({
	email: z.email("email.invalid"),
	password: z
		.string()
		.nonempty("password.required")
		.min(8, "password.minLength"),
});
export const Component = (): void => {
	useForm({
		resolver: zodResolver(loginSchema),
		mode: "onChange",
		defaultValues: {
			email: "",
			password: "",
		},
	});
};

image

Does anyone have any idea of why this happens?
Thanks

@MartinCura
Copy link

MartinCura commented Jun 24, 2025

(...)

image

Does anyone have any idea of why this happens? Thanks

Found the same thing, not sure why. I switched to using the standardSchemaResolver and it seems to work so i worked around it 🤷🏼 Not sure if you found the reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants