How to Use Zod in TypeScript Projects for Validation and Safety
Validation

How to Use Zod in TypeScript Projects for Validation and Safety

Sagar Yenkure
July 10th, 2025

Zod is one of the best libraries out there for validating data in TypeScript projects. It’s fast, type-safe, and works beautifully for both backend APIs and frontend forms.

In this guide, we’ll walk through how to:

  • Use Zod to validate incoming API requests in Node.js
  • Use Zod with React Hook Form for frontend form validation

Step 1: Installing Zod

First things first — install Zod in your project:

npm install zod
Click to Copy

If you're using it with React Hook Form:

npm install react-hook-form @hookform/resolvers
Click to Copy

Step 2: What is Zod and Why Use It?

Zod is a TypeScript-first schema validation library. That means you write your validation rules using Zod, and it automatically gives you fully typed objects.

You can use it to:

  • Safely validate user input
  • Share the same schema between backend and frontend
  • Avoid writing repetitive type definitions and manual checks

Step 3: Validating API Input in Node.js

Let’s say you’re building a user registration API. You want to make sure that the data sent to the server is actually valid — no missing fields, no bad email formats, etc.

Create a Schema

// schemas/user.schema.ts import { z } from "zod"; export const userSchema = z.object({ name: z.string().min(2, "Name must be at least 2 characters"), email: z.string().email("Please enter a valid email"), password: z.string().min(6, "Password must be at least 6 characters"), });
Click to Copy

Use the Schema in an API Route

// routes/user.ts import express from "express"; import { userSchema } from "../schemas/user.schema"; const router = express.Router(); router.post("/register", (req, res) => { const result = userSchema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.flatten().fieldErrors, }); } const user = result.data; res.status(200).json({ message: "User registered", user }); });
Click to Copy

✅ 'safeParse()' lets you check if the input is valid and safely access the typed data.


Step 4: Form Validation in React with React Hook Form + Zod

Zod works perfectly with React Hook Form. You can reuse the same schema on the frontend that you used on the backend.

Set Up the Schema

// schemas/user.schema.ts import { z } from "zod"; export const userSchema = z.object({ name: z.string().min(2, "Name must be at least 2 characters"), email: z.string().email("Please enter a valid email"), password: z.string().min(6, "Password too short"), }); export type UserSchemaType = z.infer<typeof userSchema>;
Click to Copy

Use It in a Form

// components/RegisterForm.tsx "use client"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { userSchema, UserSchemaType } from "../schemas/user.schema"; export default function RegisterForm() { const { register, handleSubmit, formState: { errors }, } = useForm<UserSchemaType>({ resolver: zodResolver(userSchema), }); const onSubmit = (data: UserSchemaType) => { console.log("Submitted data:", data); }; return ( <form onSubmit={handleSubmit(onSubmit)}> <div> <input type="text" placeholder="Name" {...register("name")} /> {errors.name && <p>{errors.name.message}</p>} </div> <div> <input type="email" placeholder="Email" {...register("email")} /> {errors.email && <p>{errors.email.message}</p>} </div> <div> <input type="password" placeholder="Password" {...register("password")} /> {errors.password && <p>{errors.password.message}</p>} </div> <button type="submit">Register</button> </form> ); }
Click to Copy

This form is fully typed and will only submit valid data — and you didn’t have to write any custom validation logic.


Step 5: Some Cool Things Zod Can Do

Transform values

Need to convert a string to a number on the fly?

const schema = z.object({ age: z.string().transform((val) => Number(val)), });
Click to Copy

Nest schemas

You can compose schemas easily:

const addressSchema = z.object({ city: z.string(), zip: z.string(), }); const userSchema = z.object({ name: z.string(), address: addressSchema, });
Click to Copy

Custom error messages

Zod lets you add readable, user-friendly errors:

z.string().min(1, { message: "This field is required" });
Click to Copy

Final Thoughts

Zod is an amazing tool for modern TypeScript development. Whether you're building APIs or forms, it helps you:

  • Avoid bugs from invalid data
  • Write cleaner code with less boilerplate
  • Share logic across your stack

If you're using TypeScript, Zod should be part of your toolkit. Give it a try in your next project — you’ll never look back.