·6 min read
JSON Schema vs Zod vs Yup: Choosing the Right Validation Library
JSON Schema, Zod, and Yup are three major approaches to data validation. JSON Schema is a language-agnostic specification, Zod is a TypeScript-first schema library, and Yup is a JavaScript validation library popular in the React ecosystem. This guide compares their approaches, syntax, performance, and ecosystem to help you choose the right tool. Use our JSON Schema Generator, JSON to Zod Schema, and JSON to Yup Schema converters to switch between them.
Feature Comparison
| Feature | JSON Schema | Zod | Yup |
|---|---|---|---|
| Language | Any (JSON-based) | TypeScript | JavaScript / TypeScript |
| Schema format | JSON object | Chainable API / object | Chainable API |
| Type inference | Third-party tools | First-class (z.infer) | InferType |
| Bundle size | Varies by implementation | ~12 KB (min+gzip) | ~25 KB (min+gzip) |
| Runtime validation | Yes | Yes (zero dependencies) | Yes |
| Async validation | No (sync only) | Yes | Yes |
| Custom error messages | Via library | Built-in | Built-in |
| Cross-platform | All languages | TypeScript/JavaScript | JavaScript |
Validation Syntax Comparison
// Schema: User with name, email, age, and tags
// JSON Schema
{
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 2 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 18, "maximum": 120 },
"tags": {
"type": "array",
"items": { "type": "string" },
"minItems": 0
}
},
"required": ["name", "email"]
}
// Zod
import { z } from 'zod';
const UserSchema = z.object({
name: z.string().min(2, 'Name must be at least 2 characters'),
email: z.string().email('Invalid email format'),
age: z.number().int().min(18).max(120).optional(),
tags: z.array(z.string()).default([])
});
type User = z.infer;
// Yup
import * as yup from 'yup';
const UserSchema = yup.object({
name: yup.string().min(2, 'Name must be at least 2 characters').required(),
email: yup.string().email('Invalid email format').required(),
age: yup.number().integer().min(18).max(120).nullable(),
tags: yup.array().of(yup.string()).default([])
});
Advanced Validation Patterns
// Conditional validation
// If user type is "business", companyName is required
// JSON Schema (if/then/else)
{
"if": { "properties": { "type": { "const": "business" } } },
"then": { "required": ["companyName"] },
"else": { "required": ["personalName"] }
}
// Zod (refine/discriminatedUnion)
const UserSchema = z.discriminatedUnion('type', [
z.object({ type: z.literal('personal'), personalName: z.string() }),
z.object({ type: z.literal('business'), companyName: z.string() })
]);
// Yup (when)
yup.object({
type: yup.string().oneOf(['personal', 'business']).required(),
companyName: yup.string().when('type', {
is: 'business',
then: (schema) => schema.required()
}),
personalName: yup.string().when('type', {
is: 'personal',
then: (schema) => schema.required()
})
});
Type Inference
// JSON Schema: Must use external tools
// json-schema-to-typescript generates:
// export interface User { name: string; email: string; age?: number; tags?: string[]; }
// Zod: Built-in type inference
const UserSchema = z.object({ name: z.string(), email: z.string().email() });
type User = z.infer;
// type User = { name: string; email: string; }
// Yup: Limited inference
import { InferType } from 'yup';
type User = InferType;
// Basic types but less accurate for complex schemas
Performance Benchmarks
| Operation | JSON Schema (Ajv) | Zod | Yup |
|---|---|---|---|
| Simple object validation | ~50K ops/s | ~200K ops/s | ~80K ops/s |
| Nested object (3 levels) | ~30K ops/s | ~120K ops/s | ~50K ops/s |
| Array of objects (10 items) | ~15K ops/s | ~60K ops/s | ~25K ops/s |
| String parsing/coercion | ~40K ops/s | ~150K ops/s | ~60K ops/s |
When to Use Each
| Use Case | Recommended | Why |
|---|---|---|
| Cross-language validation | JSON Schema | Works with any language, not just JS/TS |
| TypeScript-first project | Zod | Best type inference, smallest bundle |
| React form (Formik) | Yup | Native Formik integration |
| API request validation (backend) | JSON Schema or Zod | JSON Schema for polyglot, Zod for Node.js |
| Configuration file validation | JSON Schema | Supported by VS Code, many editors |
| Runtime type checking | Zod | Parse don't validate pattern |
Converting Between Schema Formats
Our tools make it easy to convert between formats:
- JSON Schema Generator — Generate JSON Schema from data
- JSON to Zod Schema — Generate Zod from JSON samples
- JSON to Yup Schema — Generate Yup from JSON samples
Next Steps
Choose your validation approach and use our generators: JSON Schema, Zod Schema, or Yup Schema.