Last Updated: 3/12/2026
Defining Schemas
Zod provides schema constructors for all JavaScript primitives and common data structures. This guide covers the most frequently used schema types.
Primitives
import * as z from "zod";
z.string(); // string
z.number(); // number
z.boolean(); // boolean
z.bigint(); // bigint
z.date(); // Date
z.null(); // null
z.undefined(); // undefinedStrings
String schemas support validation methods for common patterns:
const Username = z.string()
.min(3, "Username must be at least 3 characters")
.max(20, "Username cannot exceed 20 characters")
.regex(/^[a-zA-Z0-9_]+$/, "Only letters, numbers, and underscores allowed");
const Email = z.string().email("Invalid email address");
const URL = z.string().url("Invalid URL");Numbers
Number schemas provide range and format validation:
const Age = z.number()
.int("Age must be an integer")
.positive("Age must be positive")
.max(120, "Age cannot exceed 120");
const Price = z.number()
.nonnegative("Price cannot be negative")
.multipleOf(0.01, "Price must have at most 2 decimal places");Objects
Object schemas define the shape of an object:
const User = z.object({
id: z.number(),
username: z.string(),
email: z.string().email(),
age: z.number().int().positive().optional(),
});
// Type: { id: number; username: string; email: string; age?: number | undefined }By default, Zod objects are strict — they reject unknown keys:
User.parse({
id: 1,
username: "billie",
email: "billie@example.com",
extra: "field", // ✗ throws error
});To allow unknown keys, use .passthrough() or create a loose object:
const LooseUser = User.passthrough();
// or
const LooseUser = z.looseObject({ /* shape */ });Arrays
Array schemas validate each element:
const Tags = z.array(z.string())
.min(1, "At least one tag required")
.max(5, "Maximum 5 tags allowed");
// Type: string[]What’s Next
- Error Handling — Learn how to handle validation errors
- Type Inference — Extract TypeScript types from schemas
- Common Patterns — Work with optional, nullable, and default values