ajv, jsonschema, and z-schema are validators based on the official JSON Schema specification, ideal for validating structured data like API payloads against a standard contract. joi and yup use a builder pattern to define object schemas in code, offering a more developer-friendly experience for application logic and form validation. While the first group focuses on strict adherence to the JSON Schema standard, the second group prioritizes developer experience and integration with frontend frameworks like React.
Validating data is a critical part of building reliable JavaScript applications. Whether you are checking API payloads on the server or ensuring form inputs are correct on the client, you need tools that are accurate and easy to maintain. The five packages here — ajv, joi, jsonschema, yup, and z-schema — solve this problem but take two very different approaches. Let's break down how they work and when to use each one.
The biggest split is how you define what valid data looks like. ajv, jsonschema, and z-schema use the official JSON Schema standard. This means your validation rules are just data objects, which can be shared across different languages. joi and yup use a builder pattern where you write JavaScript code to describe the rules.
ajv uses a standard JSON Schema object.
// ajv: JSON Schema definition
const schema = {
type: "object",
properties: {
email: { type: "string", format: "email" }
},
required: ["email"]
};
joi uses a chainable JavaScript API.
// joi: Builder pattern
const schema = Joi.object({
email: Joi.string().email().required()
});
jsonschema uses a standard JSON Schema object.
// jsonschema: JSON Schema definition
const schema = {
type: "object",
properties: {
email: { type: "string", format: "email" }
},
required: ["email"]
};
yup uses a chainable JavaScript API similar to Joi.
// yup: Builder pattern
const schema = yup.object({
email: yup.string().email().required()
});
z-schema uses a standard JSON Schema object.
// z-schema: JSON Schema definition
const schema = {
type: "object",
properties: {
email: { type: "string", format: "email" }
},
required: ["email"]
};
Performance often depends on how the library processes the schema. ajv compiles schemas into functions for speed. Others interpret the schema every time or use different caching strategies.
ajv compiles the schema once for high performance.
// ajv: Compile then validate
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data);
joi validates directly using the schema object.
// joi: Direct validation
const { error, value } = schema.validate(data);
jsonschema validates directly with a helper function.
// jsonschema: Direct validation
const result = validator.validate(data, schema);
const valid = result.valid;
yup validates asynchronously by default.
// yup: Async validation
const valid = await schema.isValid(data);
z-schema validates directly using an instance.
// z-schema: Direct validation
const zSchema = new ZSchema();
const valid = zSchema.validate(data, schema);
When validation fails, you need clear messages to show users or log for debugging. Some libraries return rich error objects, while others require extra steps to get details.
ajv stores errors on the instance after validation.
// ajv: Access errors from instance
if (!validate(data)) {
console.log(validate.errors);
}
joi returns errors in the result object.
// joi: Errors in result
const { error } = schema.validate(data);
if (error) console.log(error.details);
jsonschema returns errors in the result object.
// jsonschema: Errors in result
const result = validator.validate(data, schema);
if (!result.valid) console.log(result.errors);
yup throws errors or returns them via catch.
// yup: Catch validation errors
try {
await schema.validate(data);
} catch (err) {
console.log(err.errors);
}
z-schema provides errors via a getter method.
// z-schema: Get last errors
if (!valid) {
console.log(zSchema.getLastErrors());
}
Not all libraries work everywhere out of the box. Some are built for Node.js servers, while others are designed to run in the browser bundle.
ajv works in both but requires bundling for browsers.
// ajv: Universal but needs bundling
import Ajv from "ajv";
// Works in Node and Webpack/Vite bundles
joi is primarily for Node.js environments.
// joi: Node.js focused
const Joi = require("joi");
// Browser support requires community builds
jsonschema is lightweight and works in browsers easily.
// jsonschema: Browser friendly
import { Validator } from "jsonschema";
// No heavy dependencies
yup is designed for browser-based React apps.
// yup: Frontend focused
import * as yup from "yup";
// Optimized for bundle size in web apps
z-schema works in both but is heavier.
// z-schema: Universal
import ZSchema from "z-schema";
// Can be bundled for web use
Despite the differences in approach, these libraries share core goals and capabilities.
// All support basic type checks
// ajv/jsonschema/z-schema: { type: "number" }
// joi/yup: Joi.number() / yup.number()
// All support required checks
// ajv/jsonschema/z-schema: "required": ["name"]
// joi/yup: .required()
// All support nesting
// ajv/jsonschema/z-schema: properties: { user: { type: "object" ... } }
// joi/yup: Joi.object({ user: Joi.object() })
// All support custom logic
// ajv: addKeyword
// joi: custom()
// yup: test()
// jsonschema/z-schema: custom format or validation
| Feature | ajv | joi | jsonschema | yup | z-schema |
|---|---|---|---|---|---|
| Schema Style | JSON Schema | Builder | JSON Schema | Builder | JSON Schema |
| Primary Use | API Validation | Backend Logic | Simple Validation | Frontend Forms | Legacy/Specific |
| Compilation | Yes (Fast) | No | No | No | No |
| Async Support | Limited | Yes | No | Yes (Native) | Limited |
| Browser Ready | Via Bundle | Limited | Yes | Yes | Via Bundle |
| Category | JSON Schema Group (ajv, jsonschema, z-schema) | Object Schema Group (joi, yup) |
|---|---|---|
| Definition | Declarative JSON objects | Imperative JavaScript code |
| Portability | High (Language agnostic) | Low (JS specific) |
| Flexibility | Strict to spec | High (Custom logic easy) |
| Learning Curve | Higher (Learn spec) | Lower (Intuitive API) |
ajv is the performance king for JSON Schema — use it for high-traffic API validation where standards matter.
joi is the backend workhorse — use it for Node.js services that need powerful data coercion and complex rules.
jsonschema is the lightweight option — use it for simple scripts or environments where you want zero fuss.
yup is the frontend favorite — use it for React forms where async validation and error messages are key.
z-schema is the legacy choice — use it only if you are maintaining older systems that already rely on it.
Final Thought: The choice comes down to where your data lives. If you are sharing schemas between backend and frontend, stick with JSON Schema (ajv). If you are building a React form or a Node API with complex logic, the builder pattern (yup or joi) will save you time.
Choose ajv if you need the fastest JSON Schema validator with support for the latest draft versions and custom keywords. It is the industry standard for validating API requests and responses in Node.js environments where performance and spec compliance matter most.
Choose joi if you want a robust, feature-rich object validator for Node.js backends or shared validation logic. It excels at complex data transformation and coercion, making it ideal for sanitizing input before it reaches your business logic.
Choose jsonschema if you need a simple, dependency-free implementation of JSON Schema validation that runs easily in both Node and browser environments without complex build steps. It is suitable for smaller projects that require standard compliance without extra features.
Choose yup if you are building React forms and need tight integration with libraries like Formik or React Hook Form. Its chainable API and built-in support for asynchronous validation make it the top choice for client-side form state management.
Choose z-schema if you are maintaining a legacy system that already depends on it or need a specific JSON Schema validator with remote reference loading built-in. For new projects, consider ajv instead due to more active maintenance and better performance.
The fastest JSON validator for Node.js and browser.
Supports JSON Schema draft-04/06/07/2019-09/2020-12 (draft-04 support requires ajv-draft-04 package) and JSON Type Definition RFC8927.
More than 100 people contributed to Ajv, and we would love to have you join the development. We welcome implementing new features that will benefit many users and ideas to improve our documentation.
Please review Contributing guidelines and Code components.
All documentation is available on the Ajv website.
Some useful site links:
Since I asked to support Ajv development 40 people and 6 organizations contributed via GitHub and OpenCollective - this support helped receiving the MOSS grant!
Your continuing support is very important - the funds will be used to develop and maintain Ajv once the next major version is released.
Please sponsor Ajv via:
Thank you.
Ajv generates code to turn JSON Schemas into super-fast validation functions that are efficient for v8 optimization.
Currently Ajv is the fastest and the most standard compliant validator according to these benchmarks:
Performance of different validators by json-schema-benchmark:
addSchema or compiled to be available)type keywordsTo install version 8:
npm install ajv
Try it in the Node.js REPL: https://runkit.com/npm/ajv
In JavaScript:
// or ESM/TypeScript import
import Ajv from "ajv"
// Node.js require:
const Ajv = require("ajv")
const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
const schema = {
type: "object",
properties: {
foo: {type: "integer"},
bar: {type: "string"},
},
required: ["foo"],
additionalProperties: false,
}
const data = {
foo: 1,
bar: "abc",
}
const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) console.log(validate.errors)
Learn how to use Ajv and see more examples in the Guide: getting started
See https://github.com/ajv-validator/ajv/releases
Please note: Changes in version 8.0.0
Please review and follow the Code of conduct.
Please report any unacceptable behaviour to ajv.validator@gmail.com - it will be reviewed by the project team.
To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerabilities via GitHub issues.
Ajv is a part of Tidelift subscription - it provides a centralised support to open-source software users, in addition to the support provided by software maintainers.