All free skills / Other majors

z-schema 12.x

Use z-schema ^12.0.0 for JSON Schema validation with synchronous and asynchronous APIs, safe results, draft-aware schemas, custom formats, and registered remote references.

For
z-schema@12.4.5
Verified
2026-09-08, 7 examples executed
Skill package
@modootoday/pmcp-z-schema@12.0.0

Use this skill for free

No PMCP login or subscription is required. Download the original instructions, or install the content-only archive with your project's package manager.

Download SKILL.md · Download package archive

npm install --save-dev https://pmcp.build/skills/z-schema/12/package.tgz

PMCP discovers the installed package's instructions. Connect your runtime after installation.

Archive integritysha512-qWOMPhHhXqsfoCEhjmq+t49d1M436M0kBe2BhAt9Ra1pzhuG6p+9NrYcI9sGGsmKy7tPFl+kvRuqZGoHtjrtEw==

Complete instructions

Verified against z-schema@12.4.5 on 2026-09-08. 7 of 7 examples executed.

z-schema ^12.0.0

Runtime and defaults

  • z-schema v12 requires Node.js 22 or later.
  • Use ZSchema.create() rather than constructing ZSchema directly. Older examples may still show new ZSchema(...).
  • The default JSON Schema dialect is draft2020-12. Draft-2019-09, draft-07, draft-06, and draft-04 are also supported.
  • Existing draft-04, draft-06, and draft-07 schemas must either declare $schema or use a matching factory option such as { version: 'draft-07' }.
  • In draft-2019-09 and draft-2020-12, format is annotation-only by default. { formatAssertions: null } restores legacy assertion behavior; { formatAssertions: true } enables vocabulary-aware assertions.

Synchronous validation

The default validator throws when validation fails. A successful call returns true.

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

const validator = ZSchema.create();
const schema = {
  type: 'object',
  properties: { answer: { type: 'number' } },
  required: ['answer'],
  additionalProperties: false,
};

assert.equal(validator.validate({ answer: 42 }, schema), true);

try {
  validator.validate({ answer: 'wrong' }, schema);
  assert.fail('validation should throw');
} catch (error) {
  assert.equal((error as Error).name, 'ValidateError');
  assert.ok(Array.isArray((error as { details: unknown[] }).details));
}

Do not expect the old boolean-plus-getLastErrors() behavior. The removed public methods include getLastError(), getLastErrors(), isValid(), compileSchema(), getMissingReferences(), getMissingRemoteReferences(), and getResolvedSchema().

Safe validation

Use { safe: true } when failure should be returned rather than thrown. The result is { valid: true } or { valid: false, err }.

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

const validator = ZSchema.create({ safe: true });
const schema = { type: 'string' };

const good = validator.validate('ok', schema);
assert.deepEqual(good, { valid: true });

const bad = validator.validate(123, schema);
assert.equal(bad.valid, false);
if (bad.valid) throw new Error('expected invalid result');
assert.ok(Array.isArray(bad.err.details));

validateSafe() and validateSchemaSafe() are also available. validateSchema() and validateSchemaSafe() validate schema documents themselves rather than instance data.

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

const validator = ZSchema.create();
const schema = { type: 'object', required: ['name'] };

assert.equal(validator.validateSchema(schema), true);
const result = validator.validateSchemaSafe({ type: 17 });
assert.equal(result.valid, false);

Draft-version migration

Version 12 changed the default from draft-07 to draft-2020-12. Select an older draft explicitly when using its schema vocabulary:

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

const validator = ZSchema.create({ version: 'draft-07' });
const schema = {
  $schema: 'http://json-schema.org/draft-07/schema#',
  type: 'array',
  items: [{ type: 'string' }],
  additionalItems: false,
};

assert.equal(validator.validate(['value'], schema), true);

When migrating schemas to draft-2020-12, the vocabulary shapes differ:

  • id becomes $id.
  • definitions becomes $defs.
  • Tuple items: [...] becomes prefixItems.
  • additionalItems becomes items alongside prefixItems.
  • dependencies becomes either dependentSchemas or dependentRequired.

Version 12 also supports unevaluatedProperties, unevaluatedItems, $dynamicRef, and $dynamicAnchor.

Asynchronous validation

Create the validator with { async: true }. Its validation methods return promises. With { async: true, safe: true }, the promise resolves to a safe result rather than rejecting for validation failure.

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

const validator = ZSchema.create({ async: true });
assert.equal(await validator.validate('ok', { type: 'string' }), true);

const safe = ZSchema.create({ async: true, safe: true });
const result = await safe.validate(123, { type: 'string' });
assert.equal(result.valid, false);

The explicit methods are validateAsync() and validateAsyncSafe(). Async format validators require the async factory option; do not call an async validator through a synchronous validator.

Custom formats

Formats can be registered on a validator. The package also exports format-management helpers, including registerFormat, unregisterFormat, getRegisteredFormats, getSupportedFormats, getFormatValidators, and isFormatSupported.

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

const validator = ZSchema.create({ formatAssertions: true });
validator.registerFormat('uppercase', (value: unknown): boolean =>
  typeof value === 'string' && value === value.toUpperCase(),
);

const schema = { type: 'string', format: 'uppercase' };
assert.equal(validator.validate('YES', schema), true);

For draft-2019-09 and draft-2020-12, registering a format does not by itself make format an assertion under the default settings. Configure formatAssertions when format failures must invalidate data. The format-management functions are also available as package exports.

Remote references

Register a remote schema before validating a $ref that points to it. In v12, setRemoteReference() is a static API; older examples that call it on an instance are outdated.

import assert from 'node:assert/strict';
import ZSchema from 'z-schema';

ZSchema.setRemoteReference('https://example.test/person.json', {
  $id: 'https://example.test/person.json',
  type: 'object',
  required: ['name'],
  properties: { name: { type: 'string' } },
});

const validator = ZSchema.create();
const schema = { $ref: 'https://example.test/person.json' };
assert.equal(validator.validate({ name: 'Ada' }, schema), true);

A schema reader can be installed with ZSchema.setSchemaReader(...) and inspected with ZSchema.getSchemaReader(). A reader is responsible for resolving the URI; remote references otherwise need registration before validation.

Recursion

The default recursion limit is 100. Deep recursive validation can produce MAX_RECURSION_DEPTH_EXCEEDED; increase it with { maxRecursionDepth: 500 } when the schema and data require a deeper limit.

What this skill does not cover

  • The command-line executable and its file-oriented invocation.
  • Browser use of the published UMD bundle.
  • Detailed error-code and error-parameter catalogs.
  • Building a filesystem-backed SchemaReader.
  • The complete TypeScript type surface beyond the public APIs described here.