zaggino/z-schema

JSON Schema validator written in JavaScript for NodeJS and Browsers

350

stars

759

commits

TypeScript

primary language

Sep 3, 2026

updated

README

z-schema

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

Coverage 90%

Install

npm install z-schema

Requires Node.js 22 or later.

Quick Start

ESM / TypeScript

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);
}

CommonJS

const ZSchema = require('z-schema');
const validator = ZSchema.create();

Browser (UMD)

<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>

CLI

npm install --global z-schema
z-schema mySchema.json
z-schema mySchema.json myData.json
z-schema --strictMode mySchema.json myData.json

Usage

ZSchema.create() returns one of four validator variants based on the async and safe options:

OptionsClassvalidate() returns
{}ZSchematrue (throws on error)
{ safe: true }ZSchemaSafe{ valid, err? }
{ async: true }ZSchemaAsyncPromise<true> (rejects)
{ async: true, safe: true }ZSchemaAsyncSafePromise<{ valid, err? }>

Sync Validation (Throw Mode)

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); // 'ValidateError'
  console.log(error.message); // summary message
  console.log(error.details); // array of { code, message, path, ... }
}

Sync Validation (Safe Mode)

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);
}

Async Validation (Throw Mode)

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);
}

Async Validation (Safe Mode)

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);
}

Schema Compilation

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);
}

Custom Format Validators

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;
});

Remote References

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 History

VersionChanges
v12Default version is draft2020-12. Full support for draft-2020-12 and draft-2019-09.
v11Default version is draft-07. Implemented draft-07 tests from JSON Schema Test Suite.
v10Default version is draft-06. Implemented draft-06 tests from JSON Schema Test Suite.
v9New factory API: ZSchema.create() replaces new ZSchema(). New cache algorithms.
v8Schemas without $schema default to draft-04. Use { version: 'none' } for the old v7 behavior.
v7Rewritten in TypeScript/ESM. Passes all JSON Schema Test Suite tests for draft-04.
v6Legacy version. Draft-04 support.

Features

See docs/features.md for the full feature list.

Options

See docs/options.md for all constructor and per-call options.

Documentation

DocumentDescription
docs/usage.mdDetailed usage guide with all validation modes, error handling, and advanced features
docs/options.mdConstructor options and per-call validation options
docs/features.mdFeature catalog with examples
docs/MIGRATION.mdMigration guide for upgrading between major versions
docs/architecture.mdInternal architecture, module structure, and public API reference
docs/conventions.mdCode style, naming, and formatting conventions
docs/testing.mdTest framework, running tests, and writing new tests
docs/contributing.mdPR workflow and contribution guidelines

Contributing

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.

Contributors

Big thanks to:

and to everyone submitting issues on GitHub

Contributors

(top 30 of 34)

zaggino

588 commits

dependabot[bot]

68 commits

sergey-shandar

20 commits

zaggino/z-schema

JSON Schema validator written in JavaScript for NodeJS and Browsers

350

stars

759

commits

TypeScript

primary language

Sep 3, 2026

updated

README

z-schema

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

Coverage 90%

Install

npm install z-schema

Requires Node.js 22 or later.

Quick Start

ESM / TypeScript

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);
}

CommonJS

const ZSchema = require('z-schema');
const validator = ZSchema.create();

Browser (UMD)

<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>

CLI

npm install --global z-schema
z-schema mySchema.json
z-schema mySchema.json myData.json
z-schema --strictMode mySchema.json myData.json

Usage

ZSchema.create() returns one of four validator variants based on the async and safe options:

OptionsClassvalidate() returns
{}ZSchematrue (throws on error)
{ safe: true }ZSchemaSafe{ valid, err? }
{ async: true }ZSchemaAsyncPromise<true> (rejects)
{ async: true, safe: true }ZSchemaAsyncSafePromise<{ valid, err? }>

Sync Validation (Throw Mode)

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); // 'ValidateError'
  console.log(error.message); // summary message
  console.log(error.details); // array of { code, message, path, ... }
}

Sync Validation (Safe Mode)

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);
}

Async Validation (Throw Mode)

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);
}

Async Validation (Safe Mode)

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);
}

Schema Compilation

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);
}

Custom Format Validators

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;
});

Remote References

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 History

VersionChanges
v12Default version is draft2020-12. Full support for draft-2020-12 and draft-2019-09.
v11Default version is draft-07. Implemented draft-07 tests from JSON Schema Test Suite.
v10Default version is draft-06. Implemented draft-06 tests from JSON Schema Test Suite.
v9New factory API: ZSchema.create() replaces new ZSchema(). New cache algorithms.
v8Schemas without $schema default to draft-04. Use { version: 'none' } for the old v7 behavior.
v7Rewritten in TypeScript/ESM. Passes all JSON Schema Test Suite tests for draft-04.
v6Legacy version. Draft-04 support.

Features

See docs/features.md for the full feature list.

Options

See docs/options.md for all constructor and per-call options.

Documentation

DocumentDescription
docs/usage.mdDetailed usage guide with all validation modes, error handling, and advanced features
docs/options.mdConstructor options and per-call validation options
docs/features.mdFeature catalog with examples
docs/MIGRATION.mdMigration guide for upgrading between major versions
docs/architecture.mdInternal architecture, module structure, and public API reference
docs/conventions.mdCode style, naming, and formatting conventions
docs/testing.mdTest framework, running tests, and writing new tests
docs/contributing.mdPR workflow and contribution guidelines

Contributing

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.

Contributors

Big thanks to:

and to everyone submitting issues on GitHub

Contributors

(top 30 of 34)

zaggino

588 commits

dependabot[bot]

68 commits

sergey-shandar

20 commits

Languages

TypeScript

98.1%

JavaScript

1.9%