TypeScript helps you prevent bugs at compile time, but it doesn't validate data coming from external sources like APIs, forms, or localStorage.

That's why Zod exists β€” to add runtime validation with static type inference.

Traditionally, developers rely on libraries like yup or manual checks. But with TypeScript gaining popularity, Zod has become the go-to choice for schema validation that integrates deeply with static types.

Let’s explore what makes Zod so effective and how to use it in real-world projects.


🎯 What is zod?

Zod is a TypeScript-first schema validation library that:

  • Parses and validates data
  • Automatically infers static types
  • Is zero-dependency and lightweight

It works in both JavaScript and TypeScript, but really shines in TypeScript projects.


πŸš€ Why zod?

  • βœ… Validates at runtime
  • βœ… Infers static TypeScript types
  • βœ… No extra dependencies
  • βœ… Ideal for frontend, backend, or fullstack apps

πŸ“¦ Installation

npm install zod

πŸ›  Basic example

import { z } from 'zod';

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

// Runtime validation
const user = UserSchema.parse({
  name: 'Pedro',
  email: 'pedro@example.com',
  age: 25,
});

If validation fails, Zod throws:

UserSchema.parse({ name: 'Pedro', email: 'not-email', age: 10 });
// ❌ Throws detailed validation error

🧠 Inferred types

Zod lets you reuse your schema as a type:

type User = z.infer<typeof UserSchema>;

This keeps types and validation perfectly in sync.


✨ Safe parsing

To avoid exceptions, use safeParse:

const result = UserSchema.safeParse(data);

if (!result.success) {
  console.log(result.error.format());
} else {
  // result.data is fully validated and typed
}

πŸ”Œ Real-world use cases

1. Validating API requests

app.post('/signup', (req, res) => {
  const result = UserSchema.safeParse(req.body);
  if (!result.success) {
    return res.status(400).json(result.error.flatten());
  }
  // req.body is now trusted
});

2. Parsing config or localstorage

const Settings = z.object({
  darkMode: z.boolean().optional(),
});

const raw = localStorage.getItem('settings');
const parsed = Settings.safeParse(JSON.parse(raw ?? '{}'));

βœ… Conclusion

Zod adds a missing layer to TypeScript: runtime safety.

You can’t trust external data just because your types say it’s valid β€” Zod ensures it really is.

If you're building apps where data crosses boundaries, Zod is a no-brainer.