contributing-to-z-schema
Contributing to z-schema
z-schema is a JSON Schema validator (draft-04 through draft-2020-12) written in TypeScript. This skill covers the development workflow, codebase navigation, and common contribution tasks.
Repository setup
git clone --recursive https://github.com/zaggino/z-schema.git
cd z-schema
npm install
If already cloned without --recursive (needed for the json-schema-spec/ submodule):
git submodule update --init --recursive
Quality checks
Run all checks before pushing:
npm run lint:check # ESLint
npm run format:check # Prettier
npm run build # TypeScript + Rollup
npm run build:tests # Type-check tests
npm test # Vitest (node + browser)
Pre-commit hooks auto-run lint + format on staged files. Pre-push hooks run build + type-check.
Codebase map
src/
index.ts → Public API (all exports)
z-schema.ts → Factory + ZSchema/ZSchemaSafe/ZSchemaAsync/ZSchemaAsyncSafe
z-schema-base.ts → Core validation orchestration
schema-compiler.ts → $ref resolution, id collection, schema compilation
schema-validator.ts → Schema-level validation against meta-schemas
json-validation.ts → Validation orchestration (validate, recurse*, collectEvaluated)
validation/ → Keyword validators split by category
shared.ts → Shared types (JsonValidatorFn), vocab helpers, caching utilities
type.ts → type, enum, const validators
numeric.ts → multipleOf, minimum, maximum, exclusiveMin/Max validators
string.ts → minLength, maxLength, pattern, format, content* validators
array.ts → items, prefixItems, contains, min/maxItems, uniqueItems validators
object.ts → properties, patternProperties, additionalProperties, required, etc.
combinators.ts → allOf, anyOf, oneOf, not, if/then/else validators
ref.ts → $dynamicRef/$recursiveRef resolution helpers
schema-cache.ts → Schema caching by URI/id
errors.ts → Error codes (Errors object) + ValidateError class
format-validators.ts → Built-in + custom format validators
report.ts → Error accumulation (Report, SchemaErrorDetail)
json-schema.ts → Common JSON Schema definitions + helpers
json-schema-versions.ts → Draft-specific type unions + version mappings
z-schema-options.ts → Options interface + defaults + normalizeOptions
z-schema-reader.ts → Schema reader type
z-schema-versions.ts → Registers bundled meta-schemas into cache
utils/ → Pure utilities (array, clone, json, uri, etc.)
schemas/ → Bundled meta-schemas (generated at build time)
Validation pipeline
- Schema compilation (
schema-compiler.ts): resolves$ref, collectsid/$id, registers in cache - Schema validation (
schema-validator.ts): validates schema against its meta-schema - JSON validation (
json-validation.ts+validation/*.ts): validates data against compiled schema — type checks, constraints, combiners (allOf/anyOf/oneOf/not),unevaluated*tracking, format checks. Keyword validators are split into modules undervalidation/by category - Report (
report.ts): errors accumulate in aReport, then convert toValidateError
Common tasks
Adding a new error code
- Add the error to the
Errorsobject insrc/errors.ts:MY_NEW_ERROR: 'Description with {0} placeholder', - Use
report.addError('MY_NEW_ERROR', [param])in the validation logic. - Write tests verifying the error code is produced.
Adding a new format validator
- Write the validator function in
src/format-validators.ts:const myFormatValidator: FormatValidatorFn = (input: unknown) => { if (typeof input !== 'string') return true; return /^pattern$/.test(input); }; - Register it in the
inbuiltValidatorsrecord:const inbuiltValidators = { // ...existing 'my-format': myFormatValidator, }; - Add tests in
test/spec/format-validators.spec.ts.
Adding a new option
- Add the option to
ZSchemaOptionsinsrc/z-schema-options.ts. - Add a default value in
defaultOptions. - If the option is part of
strictMode, add it to thestrictModeblock innormalizeOptions. - Document it in
docs/options.md. - Write tests.
Implementing a new JSON Schema keyword
- Add validation logic in the appropriate
src/validation/*.tsmodule (e.g.,array.tsfor array keywords,object.tsfor object keywords,combinators.tsfor applicators) orsrc/schema-validator.ts(for schema-level validation). The orchestration layer insrc/json-validation.tscalls into these modules. - Guard with a draft version check if the keyword is draft-specific.
- Remove relevant entries from
excludedFiles/excludedTestsintest/spec/json-schema-test-suite.common.ts. - Run the JSON Schema Test Suite to confirm compliance:
npx vitest run --silent=false --project node -t "draft2020-12/newKeyword" - Export any new types through
src/index.ts.
Modifying existing behavior
- Find the relevant module using the codebase map above.
- Make changes following code conventions (see below).
- Run the full test suite — regressions often appear in other drafts.
Test framework
- Vitest with
globals: true. - Two projects: node and browser (Playwright: Chromium, Firefox, WebKit).
- Tests live in
test/spec/.
File naming
| Suffix | Runs in |
|---|---|
*.spec.ts |
Both node and browser |
*.node-spec.ts |
Node only |
*.browser-spec.ts |
Browser only |
Running tests
npm test # all
npm run test:node # node only
npx vitest run --silent=false --project node -t "draft4/type" # single test
npm run test:coverage # coverage
Test pattern
import { ZSchema } from '../../src/z-schema.ts';
describe('Feature Name', () => {
it('should accept valid data', () => {
const validator = ZSchema.create();
expect(validator.validate('hello', { type: 'string' })).toBe(true);
});
it('should reject invalid data', () => {
const validator = ZSchema.create();
const { valid, err } = validator.validateSafe(42, { type: 'string' });
expect(valid).toBe(false);
expect(err?.details?.[0]?.code).toBe('INVALID_TYPE');
});
});
JSON Schema Test Suite
Official test cases loaded via test/spec/json-schema-test-suite.common.ts. To enable tests for a newly implemented feature, remove entries from excludedFiles / excludedTests and confirm they pass.
Code conventions
- TypeScript
strict: true, ESM with.jsimport extensions insrc/ .tsimport extensions intest/(viaallowImportingTsExtensions)import typefor type-only imports (enforced by ESLint)- Import order: type-only → side-effect → node builtins → packages → relative
- Prettier: 120 char width, single quotes, trailing commas (es5), semicolons
- Classes/types:
PascalCase— functions/variables:camelCase— errors:UPPER_SNAKE_CASE - All public API exported through
src/index.ts - Internal types stay unexported
- Schemas in
src/schemas/are generated byscripts/copy-schemas.mts— do not edit manually json-schema-spec/is a git submodule — do not commit changes to it
PR checklist
- [ ] Branch from `main`
- [ ] Changes follow code conventions
- [ ] npm run lint:check passes
- [ ] npm run format:check passes
- [ ] npm run build passes
- [ ] npm run build:tests passes
- [ ] npm test passes (node + browser)
- [ ] New public types/values exported through src/index.ts
- [ ] New features have tests
- [ ] docs/ updated if public API changed
- [ ] JSON Schema Test Suite entries un-excluded if applicable
Reference files
- references/architecture-details.md — Full module dependency diagram, factory pattern, build outputs, and internal types
More from zaggino/z-schema
writing-json-schemas
Authors JSON Schema definitions for use with z-schema validation. Use when the user needs to write a JSON Schema, define a schema for an API payload, create schemas for form validation, structure schemas with $ref and $defs, choose between oneOf/anyOf/if-then-else, design object schemas with required and additionalProperties, validate arrays with items or prefixItems, add format constraints, organize schemas for reuse, or write draft-2020-12 schemas.
87validating-json-data
Validates JSON data against JSON Schema using the z-schema library. Use when the user needs to validate JSON, check data against a schema, handle validation errors, use custom format validators, work with JSON Schema drafts 04 through 2020-12, set up z-schema in a project, compile schemas with cross-references, resolve remote $ref, configure validation options, or inspect error details. Covers sync/async modes, safe error handling, schema pre-compilation, remote references, TypeScript types, and browser/UMD usage.
74skill-creator
Create, improve, and test skills for the z-schema JSON Schema validator library. Use this skill whenever the user wants to create a new skill from scratch, turn a workflow into a reusable skill, update or refine an existing skill, write test cases for a skill, or organize reference material for a skill. Also use when someone mentions "skill", "SKILL.md", or wants to document a z-schema workflow for reuse by humans or AI agents.
65migrating-json-schemas
Migrates JSON Schemas between draft versions for use with z-schema. Use when the user wants to upgrade schemas from draft-04 to draft-2020-12, convert between draft formats, update deprecated keywords, replace id with $id, convert definitions to $defs, migrate items to prefixItems, replace dependencies with dependentRequired or dependentSchemas, adopt unevaluatedProperties or unevaluatedItems, or adapt schemas to newer JSON Schema features.
65custom-format-validators
Registers and manages custom format validators in z-schema. Use when the user needs to add custom format validation, create sync or async format validators, register formats globally or per instance, validate emails or dates or phone numbers or custom business rules with format, configure formatAssertions for vocabulary-aware behavior, use customFormats option, list registered formats, handle async format timeouts, or understand how format validation differs across JSON Schema drafts.
64handling-validation-errors
Inspects, filters, and maps z-schema validation errors for application use. Use when the user needs to handle validation errors, walk nested inner errors from anyOf/oneOf/not combinators, map error codes to user-friendly messages, filter errors with includeErrors or excludeErrors, build form-field error mappers, use reportPathAsArray, interpret SchemaErrorDetail fields like code/path/keyword/inner, or debug why validation failed.
63