Skip to Content
schemas-7lnl63oDefining Schemas

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(); // undefined

Strings

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