Skip to content
devcards.space
FrontendTools

What is Zod? Type-Safe Validation for Modern Apps

Generate runtime validation from TypeScript types with Zod. Schema definitions, parse, safeParse, type inference and React Hook Form integration.

8 minute read
Zod infographic: TypeScript-first schema validation, parse/safeParse, type inference and React Hook Form integration

Zod is a TypeScript-first schema validation library. Write a schema once and you get both your type and your runtime checks — a single, consistent way to validate everything 'untrusted' (form data, API bodies, environment variables). This guide expands the infographic, taking you from simple schemas through refinement and React Hook Form integration.

What is Zod?

A TypeScript-first schema validation library. It gives you both compile-time type safety and trustworthy runtime checks. It provides a single validation language for API responses, forms and env variables.

  • TypeScript-first schema validation
  • Runtime type safety
  • A type system you can trust

Why Zod?

Where Zod stands out among alternatives:

  • Type-safe runtime validation
  • Easy schema definition
  • Helpful type inference (z.infer)
  • Zero dependencies
  • Active, fast-growing ecosystem

Installation

A single package — installed as a runtime dependency.

bash
npm install zod

Basic Schema

Define a schema with z.object. For each field there are helpers like z.string(), z.number() and z.boolean().

ts
import { z } from "zod";

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

Parsing & Validation

schema.parse(data) validates data and throws on failure. On success it returns the type-safe value.

ts
const data = UserSchema.parse({
  name: "Ada",
  age: 30,
  email: "ada@dev.com",
});
// data: { name: string; age: number; email: string }

Safe Parse (IMPORTANT)

safeParse returns { success, data | error } without throwing. Use it when you'd rather branch with if/else than try/catch.

ts
const result = UserSchema.safeParse(input);

if (result.success) {
  console.log(result.data);
} else {
  console.error(result.error.format());
}

Type Inference (Key Feature)

z.infer<typeof Schema> derives the TypeScript type from your schema. The schema becomes the single source of truth — you don't need to write the type separately.

ts
type User = z.infer<typeof UserSchema>;
// { name: string; age: number; email: string }

Advanced Validation

Chain rules on strings and numbers: min, max, regex, email, url, uuid, length…

ts
z.string().min(3).max(20);
z.string().email();
z.string().regex(/^[a-z]+$/i);
z.number().int().positive();

Refinement (Custom Rules)

When the standard rules aren't enough, refine adds a custom check. superRefine and transform let you transform values and write cross-field rules.

ts
z.string().refine((val) => val !== "test", {
  message: "Test value is not allowed",
});

Nested Schemas

Schemas can nest — objects inside objects, arrays of objects, etc. — and you can model anything cleanly.

ts
const PostSchema = z.object({
  title: z.string(),
  author: z.object({
    name: z.string(),
    email: z.string().email(),
  }),
  tags: z.array(z.string()),
});

Use with React Hook Form (IMPORTANT)

Pass your Zod schema as a resolver via @hookform/resolvers/zod. RHF uses Zod for validation and infers types automatically.

tsx
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
});

const { register, handleSubmit } = useForm({
  resolver: zodResolver(schema),
});

Key Concepts

The pieces you'll keep reaching for:

  • schema — z.object, z.string, z.number…
  • parse / safeParse — runtime checks
  • z.infer — derive types from a schema
  • refine / superRefine — custom rules
  • transform — transform values

Use Cases

Where Zod shows up most often:

  • Form validation (RHF + Zod)
  • API request/response parsing
  • Environment variable validation
  • tRPC and Zod-based SDKs
  • Backend payload validation

Summary

Zod produces strong TypeScript types and trustworthy runtime validation from a single schema. Less unsafe code, no code generation, and a fit for almost every layer of a modern stack — forms, APIs, environment. Start with a single command and unify your validation layer.

Frequently Asked Questions

Common questions about this topic.

How is Zod different from Yup?

Yup is older and JavaScript-first. Zod was designed TypeScript-first, so its inference is much stronger. Yup is mature, but new projects tend to pick Zod.

What's the bundle size?

Around ~12kB gzip. With tree-shaking only the parts you use end up in the bundle. For perf-sensitive setups there are lighter alternatives like Valibot.

Is it used with tRPC?

Yes — tRPC prefers Zod for input/output schemas. The schema generates types for both server and client, giving you end-to-end type safety.

Is it enough for server-side validation?

Yes. Whether it's Next.js API Routes, Node.js, Bun or Deno — parsing payloads with Zod catches bad/missing input at the gate.

What is transform for?

It transforms data during validation: "42" → 42, trimming, lowercasing, defaulting, etc. The schema's output type updates accordingly.

Other infographics on connected topics.

Discover more developer infographics

Visit the homepage so you don't miss new content.

See all infographics