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

More Zod tasks

Back to the full Zod cheat sheet