Skip to content
Back to Learn
·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

FeatureJSON SchemaZodYup
LanguageAny (JSON-based)TypeScriptJavaScript / TypeScript
Schema formatJSON objectChainable API / objectChainable API
Type inferenceThird-party toolsFirst-class (z.infer)InferType
Bundle sizeVaries by implementation~12 KB (min+gzip)~25 KB (min+gzip)
Runtime validationYesYes (zero dependencies)Yes
Async validationNo (sync only)YesYes
Custom error messagesVia libraryBuilt-inBuilt-in
Cross-platformAll languagesTypeScript/JavaScriptJavaScript

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

OperationJSON Schema (Ajv)ZodYup
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 CaseRecommendedWhy
Cross-language validationJSON SchemaWorks with any language, not just JS/TS
TypeScript-first projectZodBest type inference, smallest bundle
React form (Formik)YupNative Formik integration
API request validation (backend)JSON Schema or ZodJSON Schema for polyglot, Zod for Node.js
Configuration file validationJSON SchemaSupported by VS Code, many editors
Runtime type checkingZodParse don't validate pattern

Converting Between Schema Formats

Our tools make it easy to convert between formats:

Next Steps

Choose your validation approach and use our generators: JSON Schema, Zod Schema, or Yup Schema.