refine() & superRefine() in Zod
From the Zod cheat sheet ยท Refinements & Transforms ยท verified Jul 2026
refine() & superRefine()
Add custom validation logic to any schema
typescript
// Simple refinement
const PositiveInt = z.number().refine(
(val) => Number.isInteger(val) && val > 0,
{ message: "Must be a positive integer" }
);
// Object-level refinement
const Form = z.object({
password: z.string().min(8),
confirm: z.string(),
}).refine((data) => data.password === data.confirm, {
message: "Passwords don't match",
path: ["confirm"],
});๐ก Use refine() for single conditions, superRefine() when you need multiple errors
โก Cross-field validation (like password confirm) requires object-level refine()
๐ Set { path: ["field"] } to attach the error to a specific field instead of the root
๐ข Async refinements MUST be used with parseAsync โ sync parse will throw
refinevalidationcustom