Zod is a TypeScript-first schema declaration and validation library. It allows you to define a schema once and automatically infer the static TypeScript type, ensuring that your data is always in the expected format.
- Zero dependencies: Tiny footprint.
- Type safety: Automatically generates TypeScript types from your schemas.
- Developer experience: Concise, readable, and chainable API.
- Works everywhere: Node.js, Browsers, and Deno.
- Immutable: Every method returns a new schema instance.
pnpm i zodDefine a schema, then use it to validate data.
import { z } from "zod";
// 1. Define a schema
const UserSchema = z.object({
username: z.string().min(3),
age: z.number().positive(),
email: z.string().email(),
});
// 2. Validate data
const result = UserSchema.parse({
username: "johndoe",
age: 25,
email: "john@example.com",
});
console.log(result); // { username: "johndoe", age: 25, email: "john@example.com" }Validates the data and returns it. If invalid, it throws a ZodError.
try {
UserSchema.parse({ username: "jo" }); // Throws error (too short)
} catch (e) {
console.log(e.issues);
}Returns an object with either the data or an error. Use this to avoid try/catch blocks.
const result = UserSchema.safeParse({ username: "jo" });
if (result.success) {
console.log(result.data);
} else {
console.log(result.error.format()); // User-friendly error object
}Zod supports all basic JavaScript types.
z.string();
z.number();
z.bigint();
z.boolean();
z.date();
z.null();
z.undefined();
z.any(); // Allows anything
z.unknown(); // Safer "any"You can force Zod to convert (coerce) input data to the desired type.
const schema = z.coerce.number();
schema.parse("123"); // Returns 123 (number)
schema.parse(true); // Returns 1 (number)Objects are the bread and butter of Zod.
const User = z.object({
name: z.string(),
role: z.enum(["admin", "user"]),
});
// Extend a schema
const Mod = User.extend({
permissions: z.array(z.string()),
});
// Strip unknown keys (Default Behavior)
User.parse({ name: "Alice", role: "user", extra: "ignore me" }); // { name: "Alice", role: "user" }
// Allow unknown keys
const Passthrough = User.passthrough();
// Throw if unknown keys are present
const Strict = User.strict();const StringArray = z.array(z.string());
const NumberSet = z.set(z.number());
StringArray.parse(["a", "b", "c"]);This is Zod's superpower. You don't need to write the interface/type twice!
const UserSchema = z.object({
name: z.string(),
age: z.number(),
});
// Automatically extract the TypeScript type
type User = z.infer<typeof UserSchema>;
// Now you can use 'User' as a normal TypeScript type
const myUser: User = {
name: "Bob",
age: 30,
};z.string().min(5).max(10);
z.string().email();
z.string().url();
z.string().uuid();
z.string().regex(/^[a-zA-Z]+$/);
z.string().includes("hello");
z.string().startsWith("a").endsWith("z");z.number().gt(5); // Greater than
z.number().gte(5); // Greater than or equal to
z.number().lt(10); // Less than
z.number().lte(10); // Less than or equal to
z.number().int(); // Must be an integer
z.number().positive(); // > 0Everything in Zod is required by default.
z.string().optional(); // string | undefined
z.string().nullable(); // string | null
z.string().nullish(); // string | null | undefinedAdd custom validation logic.
const PasswordSchema = z.string().refine((val) => val.length > 8, {
message: "Password must be at least 8 characters long",
});Modify the data during validation.
const TrimSchema = z.string().transform((val) => val.trim());
TrimSchema.parse(" hello "); // "hello"
const StringToNumber = z.string().transform((val) => val.length);
StringToNumber.parse("abc"); // 3When parsing fails, Zod provides a ZodError object.
const result = z.string().safeParse(123);
if (!result.success) {
console.log(result.error.issues);
/*
[
{
"code": "invalid_type",
"expected": "string",
"received": "number",
"path": [],
"message": "Expected string, received number"
}
]
*/
}- Define:
const mySchema = z... - Infer:
type MyType = z.infer<typeof mySchema> - Validate:
mySchema.parse(data)ormySchema.safeParse(data) - Handle: Manage errors if validation fails.