Overview
Zod is a schema declaration and validation library designed for TypeScript and JavaScript applications. It allows developers to define the expected shape and types of data using a fluent, object-oriented API. A core benefit of Zod is its TypeScript-first approach, which means that once a schema is defined, Zod can infer the corresponding TypeScript type, providing strong compile-time guarantees alongside runtime validation. This dual capability helps prevent common data-related bugs by catching issues both during development and when an application processes external data, such as API responses or user input.
The library is suitable for a range of use cases, including validating environment variables, ensuring the integrity of data persisted to a database, and parsing complex API payloads. Its composable nature allows for building intricate validation rules from simpler ones, supporting nested objects, arrays, unions, intersections, and custom validation logic. Zod's API is designed to be expressive and readable, often mirroring the structure of the data it validates. For instance, defining an object schema with specific properties and their types is intuitive, and these schemas can be reused across different parts of an application.
Zod is particularly well-suited for projects that prioritize type safety and robust data handling in TypeScript environments. Its ability to infer types directly from schema definitions eliminates the need for manual type declarations, reducing boilerplate and potential synchronization errors between schema and type definitions. This makes it a valuable tool for maintaining code quality in large-scale applications or projects with evolving data models. The library is also frequently integrated into full-stack frameworks and libraries to manage data validation on both frontend and backend systems, ensuring consistent data contracts across an entire application stack.
Key features
- TypeScript Inference: Automatically infers static TypeScript types from defined Zod schemas, ensuring type safety at compile time based on runtime validation rules.
- Runtime Validation: Validates data against defined schemas at runtime, catching errors from external sources like API responses or user input before they can affect application logic.
- Composable Schemas: Supports building complex schemas from simpler ones using methods for unions, intersections, arrays, objects, and more, enabling reusable validation logic.
- Custom Validators: Allows developers to define and integrate custom validation functions for specific business rules not covered by built-in types.
- Coercion Support: Provides utilities to transform input data types (e.g., string to number) during validation, simplifying data processing.
- Friendly Error Messages: Generates detailed and understandable error messages, which can be customized for better developer and user experience.
- Parsing and Transformation: Beyond validation, Zod can parse and transform data, ensuring that the output conforms to the expected schema and type.
Pricing
Zod is an open-source library distributed under the MIT License, meaning it is free to use for both personal and commercial projects without any licensing fees. The source code is publicly available, allowing for community contributions and audits.
| Feature | Free (MIT License) |
|---|---|
| Schema Definition & Validation | Included |
| TypeScript Type Inference | Included |
| Custom Validators | Included |
| Parsing & Transformation | Included |
| Community Support | Included |
Pricing as of 2026-06-03. For detailed licensing information, refer to the Zod documentation.
Common integrations
- React Hook Form: Zod schemas can be used as resolvers for form validation in React Hook Form, streamlining form data handling and error reporting.
- Express.js / Koa.js: Integrates with Node.js web frameworks to validate incoming request bodies, query parameters, and headers, ensuring API endpoint data integrity.
- tRPC: Zod is often used with tRPC to define input and output schemas for API procedures, providing end-to-end type safety across the frontend and backend.
- Next.js / Remix: Used in full-stack frameworks to validate data submitted via forms, API routes, or loaded from external sources.
- Database ORMs/ODMs: Can be used to validate data before it is persisted to a database, ensuring it conforms to defined models.
Alternatives
- Joi: A schema description language and validator for JavaScript, known for its extensive set of validation rules and error reporting.
- Yup: A JavaScript schema builder for value parsing and validation, often used in conjunction with form libraries in React.
- Valibot: A lightweight schema validation library that focuses on small bundle size and TypeScript inference, similar to Zod but with a different API design.
Getting started
To begin using Zod, install it via npm or yarn:
npm install zod
# or
yarn add zod
Here's a basic example demonstrating how to define a user schema and validate data against it:
import { z } from 'zod';
// Define a schema for a User object
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(3, { message: "Name must be 3 or more characters long" }),
email: z.string().email(),
age: z.number().int().positive().optional(),
roles: z.array(z.enum(["admin", "editor", "viewer"])).default(["viewer"]),
});
// Infer the TypeScript type from the schema
type User = z.infer;
const validUser = {
id: 'a1b2c3d4-e5f6-7890-1234-567890abcdef',
name: 'Alice Smith',
email: '[email protected]',
age: 30,
};
const invalidUser = {
id: 'invalid-uuid',
name: 'Al',
email: 'not-an-email',
};
// Validate valid data
try {
const parsedUser: User = UserSchema.parse(validUser);
console.log('Valid user:', parsedUser);
} catch (error) {
console.error('Validation error for validUser:', error);
}
// Validate invalid data
try {
const parsedInvalidUser: User = UserSchema.parse(invalidUser);
console.log('Parsed invalid user:', parsedInvalidUser);
} catch (error) {
console.error('Validation error for invalidUser:', error.errors);
}
// Example of safely parsing an unknown value
function processUserData(data: unknown) {
const result = UserSchema.safeParse(data);
if (result.success) {
console.log('Successfully processed user:', result.data);
} else {
console.error('Failed to process user data:', result.error.issues);
}
}
processUserData(validUser);
processUserData(invalidUser);
processUserData({ name: 'Bob', email: '[email protected]', roles: ['admin'] }); // Missing ID, inferred age is undefined
This example demonstrates schema definition for a User object, including various data types, validation rules (like minimum length, email format, UUID), and default values. It also shows how to use .parse() for validation with error throwing, and .safeParse() for non-throwing validation, which returns a result object indicating success or failure. The inferred User type ensures that TypeScript understands the shape of the validated data.