About

evolving · Apr 22, 2026 · 2 min read

Zod

Zod is a TypeScript-first schema validation library. It lets you describe the shape and constraints of your data as a schema, then validate real data against that schema at runtime. If the data matches, you get it back fully typed. If not, you get structured error messages explaining exactly what failed.

The reason this matters: TypeScript types only exist at compile time. Once your code runs in the browser or on a server, all the type information is gone. Zod brings that safety back to runtime — especially important at system boundaries like API inputs, form submissions, and environment variables.


Basic usage

import { z } from 'zod'

const BookingSchema = z.object({
  user_name: z.string().min(1),
  user_email: z.string().email(),
  date: z.string().date(),
  guest_count: z.number().int().positive(),
})

// Parse throws if validation fails
const booking = BookingSchema.parse(requestBody)

// safeParse returns a result object instead of throwing
const result = BookingSchema.safeParse(requestBody)
if (!result.success) {
  console.log(result.error.issues) // detailed error list
} else {
  console.log(result.data) // fully typed
}

Key features

Type inference

Zod generates TypeScript types directly from schemas. You define the schema once and get the type for free — keeping validation and types in sync automatically.

type Booking = z.infer<typeof BookingSchema>
// same as writing the interface by hand

Composable schemas

Schemas can be combined, extended, and transformed:

const BaseSchema = z.object({ id: z.string().uuid() })
const FullSchema = BaseSchema.extend({ name: z.string() })

const CoercedNumber = z.coerce.number() // converts "42" → 42

Environment variable validation

A common pattern is validating all process.env values at startup so missing variables cause a clear error immediately, not a cryptic failure later:

const EnvSchema = z.object({
  DATABASE_URL: z.string().url(),
  API_KEY: z.string().min(1),
})

export const env = EnvSchema.parse(process.env)

Zod with React Hook Form

Zod integrates cleanly with React Hook Form via @hookform/resolvers:

import { zodResolver } from '@hookform/resolvers/zod'

const form = useForm({
  resolver: zodResolver(BookingSchema),
})

The resolver runs Zod validation on form submit and maps errors to the correct fields automatically.


v4 breaking changes

Zod v4 introduced changes from v3 — .strip() behaviour, error formatting, and some method names shifted. If you're migrating from v3, read the official migration guide before assuming your schemas still work. [2]


Sources

  1. Zod Documentation
  2. Zod v4 Migration Guide