Type-safe validation
Full type safety with compile-time guarantees. Define schemas once, get validated and typed data.
Type-safe validation
Full type safety with compile-time guarantees. Define schemas once, get validated and typed data.
Zero dependencies
Lightweight core with optional integrations for Axum and other web frameworks.
Rich error messages
Detailed validation errors with full path information, plus i18n support.
Derive macros
Automatically generate schemas from Rust structs and enums with #[derive(ZodSchema)].
TypeScript codegen
Generate TypeScript Zod schemas from Rust types with #[derive(ZodTs)].
Composable schemas
Build complex validation rules from simple primitives. Reuse schemas across your codebase.
use serde_json::json;use zod_rs::prelude::*;
fn main() { let schema = object() .field("name", string().min(2).max(50)) .field("email", string().email()) .field("age", number().min(0.0).max(120.0).int());
let data = json!({ "name": "Alice", "age": 25 });
match schema.safe_parse(&data) { Ok(value) => println!("Valid: {:?}", value), Err(errors) => println!("Invalid: {}", errors), }}zod-rs is a Rust validation library that validates data at runtime using composable schemas. You define rules with primitives like string(), number(), object(), and array(), compose them into complex schemas, and call safe_parse() to validate input — getting back either a typed struct or detailed errors with the full path to each failing field (e.g. user.addresses[0].zip).
string().email().min(5)) or derive it from a struct with #[derive(ZodSchema)]safe_parse(&json_value) or validate_and_parse(&json_value) to validate and deserialize in one stepUnlike attribute-only validators such as validator and garde, zod-rs schemas are values: you can build them at runtime, store them, compose them, and reuse them across your codebase. This makes zod-rs ideal for validating API request bodies, configuration files, webhook payloads, and any untrusted input where the schema may not be known at compile time.
user.profile.email)For a detailed comparison, see Choosing a Rust Validation Library or the migration guides from validator and garde.
New to data validation in Rust? These guides cover the most common use cases:
The validator crate checks structs you have already deserialized. zod-rs validates raw JSON values directly, so parsing and validation happen in one step, schemas can be built and composed at runtime, and errors carry the full path to the failing field. See the full comparison and migration guide.
Yes. Schemas validate serde_json::Value, the derive macro honors #[serde(rename)] and #[serde(rename_all)], and enum validation matches serde’s externally tagged JSON format.
Yes. Enable the axum feature to validate request bodies with a zod-rs schema and return structured validation errors from your handlers. See the Axum integration guide.
Yes. The ZodTs derive macro and the zod-rs-ts CLI generate TypeScript Zod schemas from your Rust types, so the frontend and backend validate with the same rules. See the fullstack validation guide.
Add #[derive(ZodSchema)] to your struct and annotate fields with #[zod(email)], #[zod(min_length(3))], or other validation rules. Then call validate_and_parse() to validate JSON input and get a typed struct in one step, with full-path error messages for every failing field. See the struct validation guide and the attributes reference.
It depends on your use case. The validator crate and garde are best for checking structs you have already deserialized. zod-rs is best when validation starts at a boundary — API requests, config files, webhooks — because it validates raw JSON directly, composes schemas at runtime, generates TypeScript Zod schemas, and reports full-path errors. See the detailed comparison.