zaggino/z-schema

migrating-json-schemas

Migrates JSON Schemas between draft versions for use with z-schema.

First seen Feb 27, 2026

Installation

$ npx skills add zaggino/z-schema --skill migrating-json-schemas

Summary

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

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from zaggino/z-schema.

npx skills add zaggino/z-schema

Browse all from zaggino/z-schema

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 350
License LICENSE
Default branch main
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,066 B
  • docs SUMMARY.md 474 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 150 installs

SKILL.md

Migrating JSON Schemas Between Drafts

z-schema supports draft-04, draft-06, draft-07, draft-2019-09, and draft-2020-12. This skill covers migrating schemas between drafts and verifying them with z-schema.

Migration workflow

  1. Identify the source draft (check $schema or id/$id usage).
  2. Set the target version on the validator:

``typescript import ZSchema from 'z-schema'; const validator = ZSchema.create({ version: 'draft2020-12' }); ``

  1. Run validator.validateSchema(schema) to surface incompatibilities.
  2. Fix each reported error using the keyword mapping below.
  3. Re-validate until the schema passes.

Quick reference: keyword changes

Old keyword (draft-04) New keyword (draft-2020-12) Introduced in
id $id draft-06
definitions $defs draft-2019-09
Array-form items (tuple) prefixItems draft-2020-12
additionalItems items (when prefixItems present) draft-2020-12
exclusiveMinimum: true (boolean) exclusiveMinimum: <number> draft-06
exclusiveMaximum: true (boolean) exclusiveMaximum: <number> draft-06
dependencies (string arrays) dependentRequired draft-2019-09
dependencies (schema values) dependentSchemas draft-2019-09
$recursiveRef / $recursiveAnchor $dynamicRef / $dynamicAnchor draft-2020-12

For the complete keyword mapping with examples, see [references/keyword-mapping.md](references/keyword-mapping.md).

Common migration paths

Draft-04 → Draft-2020-12

This is the largest jump. Apply changes in order:

1. Rename id to $id

// Before (draft-04)
{ "id": "http://example.com/person.json", "type": "object" }

// After (draft-2020-12)
{ "$id": "http://example.com/person.json", "type": "object" }

2. Convert boolean exclusiveMinimum/exclusiveMaximum to numeric

// Before (draft-04)
{ "type": "number", "minimum": 0, "exclusiveMinimum": true }

// After (draft-2020-12)
{ "type": "number", "exclusiveMinimum": 0 }

Note: the minimum keyword is removed when converting to exclusiveMinimum as a number, since exclusiveMinimum: 0 means "greater than 0".

3. Rename definitions to $defs

// Before
{ "definitions": { "address": { "type": "object" } } }

// After
{ "$defs": { "address": { "type": "object" } } }

Update all $ref values that point to #/definitions/...#/$defs/....

4. Split dependencies

// Before (draft-04) — mixed dependencies
{
  "dependencies": {
    "billing_address": ["credit_card"],
    "credit_card": { "type": "object", "properties": { "cvv": { "type": "string" } } }
  }
}

// After (draft-2020-12) — split into two keywords
{
  "dependentRequired": {
    "billing_address": ["credit_card"]
  },
  "dependentSchemas": {
    "credit_card": { "type": "object", "properties": { "cvv": { "type": "string" } } }
  }
}

5. Convert tuple items to prefixItems

// Before (draft-04)
{
  "type": "array",
  "items": [{ "type": "string" }, { "type": "number" }],
  "additionalItems": false
}

// After (draft-2020-12)
{
  "type": "array",
  "prefixItems": [{ "type": "string" }, { "type": "number" }],
  "items": false
}

When items was an array (tuple validation), it becomes prefixItems. The old additionalItems becomes items.

6. Add $schema declaration

{ "$schema": "https://json-schema.org/draft/2020-12/schema" }

Draft-07 → Draft-2020-12

Smaller jump. Main changes:

  1. definitions$defs (and update $ref paths)
  2. Array-form itemsprefixItems
  3. additionalItemsitems (when prefixItems present)
  4. dependenciesdependentRequired / dependentSchemas
  5. Consider adopting unevaluatedProperties / unevaluatedItems for stricter validation of combined schemas

Draft-2019-09 → Draft-2020-12

Minimal changes:

  1. Array-form itemsprefixItems, additionalItemsitems
  2. $recursiveRef/$recursiveAnchor$dynamicRef/$dynamicAnchor

Verifying a migrated schema

After migration, validate the schema itself against the target draft's meta-schema:

import ZSchema from 'z-schema';

const validator = ZSchema.create({ version: 'draft2020-12' });

try {
  validator.validateSchema(migratedSchema);
  console.log('Schema is valid for draft-2020-12');
} catch (err) {
  console.log('Schema issues:', err.details);
}

Then test data validation to confirm behavior is unchanged:

// Test with known-good data
validator.validate(knownGoodData, migratedSchema);

// Test with known-bad data
const { valid } = validator.validateSafe(knownBadData, migratedSchema);
if (valid) {
  console.warn('Migration issue: previously invalid data now passes');
}

Backward compatibility

If schemas must work across multiple draft versions, use version: 'none' and set $schema in each schema to declare its own draft:

const validator = ZSchema.create({ version: 'none' });

Reference files

  • [references/keyword-mapping.md](references/keyword-mapping.md) — Complete keyword mapping across all drafts with before/after examples