Fast, lightweight JSON Schema validator for Node.js and browsers — full support for draft-04, draft-06, draft-07, draft-2019-09, and draft-2020-12 (latest)
Fast, lightweight JSON Schema validator for Node.js and browsers with full support for the latest JSON Schema draft (2020-12), plus draft-2019-09, draft-07, draft-06, and draft-04.
npm install z-schema
Requires Node.js 22 or later.
import ZSchema from 'z-schema';
const validator = ZSchema.create();
try {
validator.validate({ name: 'Alice' }, { type: 'object', properties: { name: { type: 'string' } } });
console.log('Valid');
} catch (error) {
console.log('Invalid:', error.details);
}
const ZSchema = require('z-schema');
const validator = ZSchema.create();
<script src="z-schema/umd/ZSchema.min.js"></script>
<script>
const validator = ZSchema.create();
try {
validator.validate('hello', { type: 'string' });
} catch (error) {
console.log(error.details);
}
</script>
npm install --global z-schema
z-schema mySchema.json
z-schema mySchema.json myData.json
z-schema --strictMode mySchema.json myData.json
ZSchema.create() returns one of four validator variants based on the async and safe options:
| Options | Class | validate() returns |
|---|---|---|
{} | ZSchema | true (throws on error) |
{ safe: true } | ZSchemaSafe | { valid, err? } |
{ async: true } | ZSchemaAsync | Promise<true> (rejects) |
{ async: true, safe: true } | ZSchemaAsyncSafe | Promise<{ valid, err? }> |
By default, validate throws a ValidateError on failure. The error has a details array with structured error info.
const validator = ZSchema.create(); // returns ZSchema
try {
validator.validate(json, schema); // returns true
} catch (error) {
console.log(error.name); // 'z-schema validation error'
console.log(error.message); // summary message
console.log(error.details); // array of { code, message, path, ... }
}
Use { safe: true } to get a ZSchemaSafe instance whose validate() returns a result object instead of throwing.
const validator = ZSchema.create({ safe: true }); // returns ZSchemaSafe
const result = validator.validate(json, schema); // { valid: boolean, err?: ValidateError }
if (!result.valid) {
console.log(result.err!.details);
}
Pass { async: true } to support async format validators. Returns a ZSchemaAsync instance whose validate() returns a Promise.
const validator = ZSchema.create({ async: true }); // returns ZSchemaAsync
try {
await validator.validate(json, schema); // Promise<true>
} catch (error) {
console.log(error.details);
}
Combine both options to get a ZSchemaAsyncSafe instance — the promise always resolves (never rejects) with a result object.
const validator = ZSchema.create({ async: true, safe: true }); // returns ZSchemaAsyncSafe
const result = await validator.validate(json, schema); // Promise<{ valid, err? }>
if (!result.valid) {
console.log(result.err!.details);
}
Pre-compile schemas at startup to validate $ref references and cache compiled schemas.
const validator = ZSchema.create();
const schemas = [
{ id: 'person', type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
{ id: 'team', type: 'object', properties: { lead: { $ref: 'person' } } },
];
try {
validator.validateSchema(schemas);
} catch (error) {
console.log('Schema errors:', error.details);
}
Register custom format validators for sync or async checks.
const validator = ZSchema.create();
// Sync format
validator.registerFormat('uppercase', (value: unknown): boolean => {
return typeof value === 'string' && value === value.toUpperCase();
});
// Async format
validator.registerFormat('user-exists', async (value: unknown): Promise<boolean> => {
if (typeof value !== 'number') return false;
const user = await db.getUserById(value);
return user != null;
});
If your schemas reference remote URIs, register them before validation.
const validator = ZSchema.create();
// Register a remote schema manually
validator.setRemoteReference('http://example.com/person.json', personSchema);
// Or set a schema reader to load them automatically
ZSchema.setSchemaReader((uri: string) => {
const filePath = path.resolve(__dirname, 'schemas', uri + '.json');
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
});
| Version | Changes |
|---|---|
| v12 | Default version is draft2020-12. Full support for draft-2020-12 and draft-2019-09. |
| v11 | Default version is draft-07. Implemented draft-07 tests from JSON Schema Test Suite. |
| v10 | Default version is draft-06. Implemented draft-06 tests from JSON Schema Test Suite. |
| v9 | New factory API: ZSchema.create() replaces new ZSchema(). New cache algorithms. |
| v8 | Schemas without $schema default to draft-04. Use { version: 'none' } for the old v7 behavior. |
| v7 | Rewritten in TypeScript/ESM. Passes all JSON Schema Test Suite tests for draft-04. |
| v6 | Legacy version. Draft-04 support. |
See docs/features.md for the full feature list.
See docs/options.md for all constructor and per-call options.
| Document | Description |
|---|---|
| docs/usage.md | Detailed usage guide with all validation modes, error handling, and advanced features |
| docs/options.md | Constructor options and per-call validation options |
| docs/features.md | Feature catalog with examples |
| docs/MIGRATION.md | Migration guide for upgrading between major versions |
| docs/architecture.md | Internal architecture, module structure, and public API reference |
| docs/conventions.md | Code style, naming, and formatting conventions |
| docs/testing.md | Test framework, running tests, and writing new tests |
| docs/contributing.md | PR workflow and contribution guidelines |
This repository uses submodules. Clone with:
git clone --recursive https://github.com/zaggino/z-schema.git
See docs/contributing.md for the full contribution guide.
Big thanks to:
and to everyone submitting issues on GitHub