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

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "migrating-json-schemas" with this command: npx skills add zaggino/z-schema/zaggino-z-schema-migrating-json-schemas

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:
    import ZSchema from 'z-schema';
    const validator = ZSchema.create({ version: 'draft2020-12' });
    
  3. Run validator.validateSchema(schema) to surface incompatibilities.
  4. Fix each reported error using the keyword mapping below.
  5. Re-validate until the schema passes.

Quick reference: keyword changes

Old keyword (draft-04)New keyword (draft-2020-12)Introduced in
id$iddraft-06
definitions$defsdraft-2019-09
Array-form items (tuple)prefixItemsdraft-2020-12
additionalItemsitems (when prefixItems present)draft-2020-12
exclusiveMinimum: true (boolean)exclusiveMinimum: <number>draft-06
exclusiveMaximum: true (boolean)exclusiveMaximum: <number>draft-06
dependencies (string arrays)dependentRequireddraft-2019-09
dependencies (schema values)dependentSchemasdraft-2019-09
$recursiveRef / $recursiveAnchor$dynamicRef / $dynamicAnchordraft-2020-12

For the complete keyword mapping with examples, see 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

writing-json-schemas

No summary provided by upstream source.

Repository SourceNeeds Review
General

custom-format-validators

No summary provided by upstream source.

Repository SourceNeeds Review
General

contributing-to-z-schema

No summary provided by upstream source.

Repository SourceNeeds Review
General

skill-creator

No summary provided by upstream source.

Repository SourceNeeds Review