Overview

Zod is an open-source, TypeScript-first schema declaration and validation library. It allows developers to define the expected shape of data using a concise, fluent API. Once a schema is defined, Zod can validate any JavaScript value against that schema, ensuring data integrity at runtime. A core strength of Zod is its deep integration with TypeScript, providing automatic type inference from the schema definitions. This means that once a schema is defined, TypeScript understands the validated data's type without requiring explicit type declarations, reducing boilerplate and improving developer experience.

The library is particularly well-suited for scenarios requiring strict data validation, such as parsing untrusted data from API responses, validating user input from forms, or defining the structure of configuration objects. Zod's approach emphasizes immutability and composability, allowing complex schemas to be built from simpler ones. It supports a wide range of data types, including strings, numbers, booleans, objects, arrays, unions, intersections, and literal values, along with advanced validation rules like min/max lengths, regex patterns, and custom validation functions. Error messages generated by Zod are designed to be human-readable and facilitate debugging, often pinpointing the exact location and reason for a validation failure.

Compared to other validation libraries like Joi's validation syntax, Zod often provides a more concise way to define schemas directly within TypeScript, benefiting from its type inference capabilities. Its runtime validation complements TypeScript's compile-time checks, closing the gap where data enters the application from external sources. The library's design focuses on developer productivity, offering clear documentation and a predictable API surface for common validation patterns.

Key features

  • TypeScript Inference: Automatically infers TypeScript types directly from schema definitions, eliminating manual type declarations.
  • Runtime Validation: Validates JavaScript values against defined schemas during execution, ensuring data correctness.
  • Fluent API: Provides a chaining syntax for defining schemas and applying transformations, enhancing readability and ease of use.
  • Schema Composition: Supports combining multiple schemas using unions, intersections, and object merging to build complex data structures.
  • Custom Validations: Allows developers to define custom validation logic using .refine() and .superRefine() methods for specific use cases.
  • Error Handling: Generates detailed, human-readable error messages for validation failures, aiding in debugging and user feedback.
  • Coercion and Transforms: Includes methods for transforming input data (e.g., string to number) before validation, enhancing data processing pipelines.
  • Asynchronous Validation: Supports asynchronous validation logic, useful for checks that require database lookups or external API calls.
  • Strict Object Schemas: Offers options to disallow unknown keys in objects, enforcing strict data structures.

Pricing

Zod is an open-source project distributed under the MIT License. It is freely available for use in both commercial and personal projects without any licensing costs.

Product/Service Details Cost (as of 2026-06-18)
Zod library Schema declaration and validation library for TypeScript/JavaScript Free

Common integrations

Zod is frequently integrated into various parts of a development stack due to its versatile nature in data validation:

  • API Routes & Endpoints: Used with frameworks like Next.js, Express, or Fastify to validate incoming request bodies, query parameters, and headers.
  • Frontend Forms: Integrated with UI libraries such as React Hook Form or Formik to validate user input client-side before submission.
  • Database ORMs/ODMs: Applied to validate data before persisting it to a database, ensuring consistency with schema definitions.
  • Environment Variables: Utilized to validate application environment variables at startup, ensuring all necessary configurations are correctly set.
  • RPC and GraphQL Servers: Employed to validate input arguments and ensure output types conform to defined schemas.
  • Data Transformation Pipelines: Used as part of ETL processes or data processing layers to ensure data conforms to expected structures.

Alternatives

  • Joi: A powerful schema description language and data validator for JavaScript, known for its extensive feature set and long history in the Node.js ecosystem.
  • Yup: A JavaScript schema builder for value parsing and validation, often favored for its concise API and integration with form libraries.
  • Valibot: A lightweight schema library with a focus on size and performance, designed for both TypeScript and JavaScript.

Getting started

To begin using Zod, you first need to install it via npm or yarn. Then, you can define a schema and use it to validate data. The following example demonstrates defining a simple user schema and attempting to validate both valid and invalid data against it.

import { z } from 'zod';

// 1. Define a schema for a User
const userSchema = z.object({
  id: z.string().uuid('Invalid UUID format'),
  username: z.string().min(3, 'Username must be at least 3 characters long'),
  email: z.string().email('Invalid email address'),
  age: z.number().int().positive('Age must be a positive integer').optional(),
  roles: z.array(z.literal('admin').or(z.literal('editor')).or(z.literal('viewer'))).default(['viewer']),
  createdAt: z.preprocess((arg) => new Date(arg as string), z.date()),
});

type User = z.infer; // Infer the TypeScript type from the schema

// 2. Example of valid data
const validUserData = {
  id: 'a1b2c3d4-e5f6-7890-1234-567890abcdef',
  username: 'john_doe',
  email: '[email protected]',
  age: 30,
  createdAt: '2023-01-15T10:00:00Z'
};

// 3. Example of invalid data
const invalidUserData = {
  id: 'not-a-uuid',
  username: 'jd',
  email: 'invalid-email',
  age: -5,
  roles: ['unknown_role'],
  createdAt: 'not-a-date'
};

// 4. Validate valid data
try {
  const user: User = userSchema.parse(validUserData);
  console.log('Valid user data:', user);
  // Access properties with full TypeScript type safety:
  console.log('User email:', user.email);
} catch (error) {
  console.error('Validation failed for valid data:', error);
}

console.log('\n--- Attempting to validate invalid data ---\n');

// 5. Validate invalid data
try {
  const user: User = userSchema.parse(invalidUserData);
  console.log('Invalid user data:', user); // This line will not be reached
} catch (error) {
  console.error('Validation failed for invalid data:', error.errors);
  // error.errors will contain an array of ZodIssue objects detailing all failures
  error.errors.forEach(issue => {
    console.error(`Path: ${issue.path.join('.')}, Message: ${issue.message}, Code: ${issue.code}`);
  });
}

// 6. Using .safeParse for non-throwing validation
const result = userSchema.safeParse(invalidUserData);
if (!result.success) {
  console.error('\nSafe parse failed. Errors:', result.error.errors);
} else {
  console.log('\nSafe parse succeeded. Data:', result.data);
}

This example demonstrates how to define a schema with various types and validation rules, including UUID format, minimum length, email format, positive integers, optional fields, default values, and array of literals. It also shows how to preprocess data, such as converting a string to a Date object. The .parse() method throws an error on invalid data, while .safeParse() returns a result object indicating success or failure without throwing, allowing for more controlled error handling. The inferred User type ensures that once data is validated, TypeScript provides strong type checking for its properties, enhancing code reliability and maintainability.