Question
How do I define a custom validator in zod?
About colinhacks/zod · 2 messages · last activity 7/12/2026
How do I define a custom validator in zod?
Perfect! Zod provides the .refine() method for custom validators. Based on the source code, here's how to use it:
.refine()The .refine() method allows you to add custom validation logic to any Zod schema [packages/zod/src/v3/types.ts:L318-L357].
Basic syntax:
schema.refine(
check: (value) => boolean | Promise<boolean>,
message?: string | CustomErrorParams | ((value) => CustomErrorParams)
)
Parameters:
check: A function that receives the parsed value and returns a boolean (or Promise<boolean>). Return true if valid, false if invalid.message (optional): An error message, a function that generates error properties, or a custom error params object.Example:
z.string()
.refine((val) => val.length > 0, "Cannot be empty")
.refine((val) => val.startsWith("A"), "Must start with A")
Async validation:
z.string()
.refine(async (val) => {
// Call API, database, etc.
const isValid = await checkUsername(val);
return isValid;
}, "Username already taken")
Custom error object:
z.object({ password: z.string(), confirm: z.string() })
.refine((val) => val.password === val.confirm, {
message: "Passwords don't match",
path: ["confirm"], // Set which field the error appears on
})
The .refine() method returns a ZodEffects schema that wraps your original schema with the additional validation logic.
FOLLOW_UPS:
superRefine() for advanced customization?.refine()?Want to ask your own question?
Open chat for colinhacks/zodPublic Q&A. Generated by RepoPilot from the actual source of colinhacks/zod. AI answers can be incomplete or stale — verify before relying on them.