Skip to main content

Overview

Zod provides two methods for custom validation:
  • .refine() - Simple custom validation with a boolean check
  • .superRefine() - Advanced validation with full control over error messages and multiple issues
Both methods run after the base schema validation succeeds.

.refine()

Add custom validation logic with a simple check function.

Signature

(data) => boolean | Promise<boolean>
required
Function that returns true if validation passes, false if it fails
string | RefinementOptions
Error message string or options object
Returns: The schema with refinement applied

Basic Usage

Custom Error Paths

Specify which field the error applies to:

Async Refinements

.superRefine()

Advanced validation with full control over error reporting.

Signature

Output
required
The validated data
RefinementCtx
required
Context object with addIssue() method
Returns: The schema with refinement applied

Basic Usage

Adding Issues

The ctx.addIssue() method accepts several forms:

Full Issue Object

String Shorthand

Refinement Options

Error Messages

Error Paths

Aborting Validation

Stop validation on first error:

Fatal Flag

Similar to abort, but set on the issue:

Continue Flag

Control whether subsequent refinements run:

Conditional Refinements

Use the when option to conditionally run refinements:

Type Narrowing

Type Guard Refinements

Use type guards to narrow the output type:

Non-Type-Guard Refinements

Regular refinements don’t narrow types:

Common Patterns

Either/Or Fields

Cross-Field Validation

Unique Array Elements

Complex Business Rules

Async Database Validation

Multiple Validation Rules

Chaining Refinements

You can chain multiple refinements:

Error Examples

Basic Refinement Error

SuperRefine Multiple Errors

Best Practices

Use refine for simple checks

Use .refine() when you just need a true/false validation. It’s simpler and more readable.

Use superRefine for complex validation

Use .superRefine() when you need multiple errors, custom error codes, or fine control over error paths.

Provide helpful error messages

Error messages should clearly explain what’s wrong and how to fix it.

Set appropriate paths

Point errors to the specific field that’s invalid using the path option.

Consider performance

Refinements run after schema validation. Expensive checks (like database calls) should be async and may benefit from caching.

Validate early

Use base schema validation for simple checks. Reserve refinements for complex business logic that requires multiple fields.

Comparison

See Also