Special Sponsor:PromptBuilder— Fast, consistent prompt creation powered by 1,000+ expert templates.
Make your Product visible here.Contact Us

Zod Cheatsheet

Quick reference for Zod schema validation — primitives, objects, arrays, unions, transforms, and error handling.

Installation & Import

npm install zod

import { z } from 'zod';

Primitive Types

z.string()
z.number()
z.boolean()
z.bigint()
z.date()
z.null()
z.undefined()
z.void()
z.any()
z.unknown()
z.never()

String Validations

z.string().min(3)
z.string().max(100)
z.string().length(10)
z.string().email()
z.string().url()
z.string().uuid()
z.string().regex(/^[a-z]+$/)
z.string().includes("foo")
z.string().startsWith("http")
z.string().endsWith(".com")
z.string().trim()
z.string().toLowerCase()
z.string().toUpperCase()

Number Validations

z.number().min(0)
z.number().max(100)
z.number().int()
z.number().positive()
z.number().negative()
z.number().nonnegative()
z.number().multipleOf(5)
z.number().finite()
z.number().safe() // Number.MIN_SAFE_INTEGER to MAX_SAFE_INTEGER

Objects

const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().email().optional(),
});

// Infer TypeScript type
type User = z.infer<typeof UserSchema>;

// Parse (throws on invalid)
const user = UserSchema.parse(data);

// Safe parse (returns { success, data } or { success, error })
const result = UserSchema.safeParse(data);
if (result.success) console.log(result.data);

// Partial — all fields optional
UserSchema.partial();

// Pick / Omit
UserSchema.pick({ id: true, name: true });
UserSchema.omit({ email: true });

// Extend
UserSchema.extend({ role: z.string() });

// Merge
UserSchema.merge(OtherSchema);

Arrays

z.array(z.string())
z.array(z.number()).min(1)
z.array(z.number()).max(10)
z.array(z.number()).length(3)
z.array(z.number()).nonempty()

// Tuple — fixed-length, typed positions
z.tuple([z.string(), z.number()])
z.tuple([z.string(), z.number()]).rest(z.boolean())

Unions & Intersections

// Union
z.union([z.string(), z.number()])
// shorthand
z.string().or(z.number())

// Discriminated union (more efficient parsing)
z.discriminatedUnion("type", [
  z.object({ type: z.literal("circle"), radius: z.number() }),
  z.object({ type: z.literal("square"), side: z.number() }),
]);

// Intersection
z.intersection(SchemaA, SchemaB)
// shorthand
SchemaA.and(SchemaB)

// Enum
z.enum(["admin", "user", "guest"])
z.nativeEnum(MyEnum) // TypeScript enum

Optional, Nullable, Default

z.string().optional()     // string | undefined
z.string().nullable()     // string | null
z.string().nullish()      // string | null | undefined
z.string().default("anon") // use default if undefined
z.string().catch("fallback") // use fallback on parse error

Transforms & Refinements

// Transform output
z.string().transform(val => val.toUpperCase())

// Refine with custom validation
z.string().refine(val => val.length > 3, {
  message: "Must be longer than 3 characters",
})

// superRefine for multiple issues
z.object({ start: z.date(), end: z.date() }).superRefine((val, ctx) => {
  if (val.end < val.start) {
    ctx.addIssue({ code: z.ZodIssueCode.custom, message: "end must be after start" });
  }
})

// Preprocess input before parsing
z.preprocess(val => Number(val), z.number())

Error Handling

const result = schema.safeParse(data);

if (!result.success) {
  // Flat error map
  console.log(result.error.flatten());
  // { fieldErrors: { name: ["Required"] }, formErrors: [] }

  // Full error details
  result.error.issues.forEach(issue => {
    console.log(issue.path, issue.message);
  });
}

// Custom error messages
z.string({ required_error: "Name is required" })
z.string().min(3, { message: "At least 3 characters" })

Frequently Asked Questions

What is Zod used for?

Zod is a TypeScript-first schema validation library. It validates data at runtime — API responses, form inputs, environment variables — and automatically infers TypeScript types from schemas so you only define the shape once.

What is the difference between parse and safeParse in Zod?

parse() throws a ZodError if validation fails. safeParse() returns { success: true, data } or { success: false, error } without throwing. Use safeParse() when you want to handle errors gracefully instead of catching exceptions.

How do I get TypeScript types from a Zod schema?

Use z.infer<typeof YourSchema>. Example: const UserSchema = z.object({ name: z.string() }); type User = z.infer<typeof UserSchema>. The TypeScript type is derived from the schema automatically — no need to write it separately.

Can Zod validate nested objects and arrays?

Yes. Nest z.object() schemas inside other schemas for nested objects. Use z.array(schema) for arrays. Zod recursively validates each level and reports errors with the full dot-notation path.

How do I handle optional and nullable fields in Zod?

Use .optional() for fields that can be undefined, .nullable() for fields that can be null, and .nullish() for fields that can be both. Use .default(value) to provide a fallback when the field is undefined.

From the blog

View all →

Generate a Zod schema from JSON automatically?

Use the JSON to Zod Converter →