Skip to main content

jsonschema-changelog

Build Status Coverage License: MIT

Detect, document, and manage changes between JSON Schema versions.

Part of the Búho Zurdo ecosystem 🦉


🎯 Overview

jsonschema-changelog is a powerful tool for managing JSON Schema evolution in production systems. It helps you:

  • Detect all changes between schema versions (properties, types, constraints, etc.)
  • Classify changes as breaking, non-breaking, or deprecations
  • Generate changelogs in Markdown, JSON, or HTML formats
  • Validate backward and forward compatibility
  • Create migration scripts for data transformation

Perfect for APIs, LIMS (Laboratory Information Management Systems), and any system where data schemas evolve over time.

📦 Installation

pip install jsonschema-changelog

Or with development dependencies:

pip install jsonschema-changelog[dev]

🚀 Quick Start

Python API

from jsonschema_changelog import SchemaDiff, ChangeClassifier, ChangelogGenerator

# Define your schemas
old_schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "status": {"type": "string", "enum": ["active", "inactive"]}
    },
    "required": ["name"]
}

new_schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "status": {"type": "string", "enum": ["active", "inactive", "pending"]},
        "email": {"type": "string", "format": "email"}  # New field
    },
    "required": ["name"]
}

# Detect changes
differ = SchemaDiff(old_version="1.0.0", new_version="2.0.0")
diff_result = differ.compare(old_schema, new_schema)

print(f"Found {diff_result.change_count} changes")

# Classify changes
classifier = ChangeClassifier()
classification = classifier.classify(diff_result)

print(f"Breaking: {len(classification.breaking_changes)}")
print(f"Non-breaking: {len(classification.non_breaking_changes)}")
print(f"Compatible: {classification.is_compatible}")

# Generate changelog
generator = ChangelogGenerator(title="API Schema Changelog")
changelog = generator.generate(classification)
markdown = generator.to_markdown(changelog)
print(markdown)

Command Line

# Compare two schemas
jsonschema-changelog diff old.json new.json

# Generate changelog
jsonschema-changelog changelog old.json new.json --format markdown -o CHANGELOG.md

# Validate compatibility (fails on breaking changes)
jsonschema-changelog validate old.json new.json --fail-on-breaking

# Generate migration script
jsonschema-changelog migrate old.json new.json --language python -o migrate.py

# Show schema information
jsonschema-changelog info schema.json

📋 Types of Changes Detected

Properties

  • ➕ Added properties
  • ➖ Removed properties
  • 🔄 Modified properties (type, constraints, etc.)

Required Fields

  • 🔒 Fields becoming required
  • 🔓 Fields becoming optional

Types

  • 📝 Type changes (string → integer, etc.)
  • 📋 Type unions (adding/removing types)

Constraints

  • 📏 Length constraints (minLength, maxLength)
  • 🔢 Numeric constraints (minimum, maximum)
  • 📊 Array constraints (minItems, maxItems)

Enums

  • ✅ Added enum values
  • ❌ Removed enum values

Other

  • 📄 Format changes (email, date-time, etc.)
  • 🔤 Pattern changes (regex)
  • 📚 $ref changes
  • ⚠️ Deprecations
  • 📝 Documentation changes

🏷️ Change Classification

Changes are automatically classified by their impact:

🚨 Breaking Changes

  • Removing a property
  • Making a field required
  • Reducing enum values
  • Making constraints stricter (higher minLength, lower maximum)
  • Changing type to a narrower type

✨ Non-Breaking Changes

  • Adding optional properties
  • Making a field optional
  • Adding enum values
  • Relaxing constraints
  • Adding nullable to types

⚠️ Deprecations

  • Marking fields as deprecated
  • Adding deprecation notices in descriptions

📝 Documentation Changes

  • Title/description updates
  • Example changes

🔧 API Reference

SchemaDiff

from jsonschema_changelog import SchemaDiff

differ = SchemaDiff(
    old_version="1.0.0",
    new_version="2.0.0",
    include_documentation=True  # Include title/description changes
)

result = differ.compare(old_schema, new_schema)

# Access changes
for change in result.changes:
    print(f"{change.change_type}: {change.path}")
    print(f"  {change.description}")

ChangeClassifier

from jsonschema_changelog import ChangeClassifier

classifier = ChangeClassifier(strict_mode=False)
classification = classifier.classify(diff_result)

# Access classified changes
for change in classification.breaking_changes:
    print(f"🚨 {change.impact_description}")
    print(f"   Migration: {change.migration_hint}")

ChangelogGenerator

from jsonschema_changelog import ChangelogGenerator

generator = ChangelogGenerator(
    title="My API Changelog",
    description="Track schema changes",
    include_documentation=False
)

changelog = generator.generate(classification, date="2024-01-15")

# Multiple formats
markdown = generator.to_markdown(changelog)
json_output = generator.to_json(changelog)
html = generator.to_html(changelog)

CompatibilityValidator

from jsonschema_changelog import CompatibilityValidator

validator = CompatibilityValidator(strict_mode=False)
result = validator.validate(old_schema, new_schema)

print(f"Level: {result.level}")  # FULL, BACKWARD, FORWARD, or NONE
print(f"Backward compatible: {result.is_backward_compatible}")
print(f"Forward compatible: {result.is_forward_compatible}")

for issue in result.issues:
    print(f"Issue: {issue.description}")
    print(f"Suggestion: {issue.suggestion}")

MigrationStrategy

from jsonschema_changelog.migration import MigrationStrategy

strategy = MigrationStrategy()
plan = strategy.generate(classification)

# Generate migration scripts
python_script = plan.to_script("python")
js_script = plan.to_script("javascript")

# Execute migration on data
migrated_data = strategy.execute(plan, original_data)

🔄 CI/CD Integration

GitHub Actions

name: Schema Validation

on:
  pull_request:
    paths:
      - 'schemas/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - run: pip install jsonschema-changelog

      - name: Validate schema compatibility
        run: |
          jsonschema-changelog validate \
            schemas/schema_v1.json \
            schemas/schema_v2.json \
            --fail-on-breaking

      - name: Generate changelog
        if: always()
        run: |
          jsonschema-changelog changelog \
            schemas/schema_v1.json \
            schemas/schema_v2.json \
            --format markdown \
            --output SCHEMA_CHANGELOG.md

      - name: Upload changelog
        uses: actions/upload-artifact@v4
        with:
          name: schema-changelog
          path: SCHEMA_CHANGELOG.md

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: schema-compatibility
        name: Check Schema Compatibility
        entry: jsonschema-changelog validate
        language: python
        files: \.json$
        args: ['schemas/current.json', 'schemas/proposed.json']

🏥 LIMS Use Case

This tool was designed with Laboratory Information Management Systems in mind:

# Validate that patient data schema changes don't break existing records
from jsonschema_changelog import CompatibilityValidator

validator = CompatibilityValidator()
result = validator.validate(
    old_schema=patient_schema_v1,
    new_schema=patient_schema_v2,
    old_version="1.0.0",
    new_version="2.0.0"
)

if not result.is_backward_compatible:
    print("⚠️ Breaking changes detected!")
    print("Existing patient records may be affected.")
    
    for suggestion in result.suggestions:
        print(f"• {suggestion}")

🛣️ Roadmap

  • JSON Schema Draft 2020-12 full support
  • Schema versioning with Git integration
  • Visual diff in HTML output
  • Migration validation with sample data
  • OpenAPI/Swagger schema support
  • AsyncAPI schema support
  • Database schema comparison

🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

📄 License

MIT License - see LICENSE for details.


Búho Zurdo
Part of the Búho Zurdo ecosystem
Building reliable software, one schema at a time

Metadata

Release files for jsonschema-changelog 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jsonschema-changelog 0.1.5
File Size Uploaded
jsonschema_changelog-0.1.5.tar.gz 40.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jsonschema-changelog 0.1.5
File Interpreter ABI Platform
jsonschema_changelog-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 46.1 kB

Release files / jsonschema_changelog-0.1.5.tar.gz

Download URL jsonschema_changelog-0.1.5.tar.gz
Size 40.3 kB
Tags Source
SHA-256 checksum
How to use checksums
2a232d3b2050d8887dfd14f687fda6fb107cdd757f5210904b52dd5adfec8a11
BLAKE2b-256 checksum
How to use checksums
4cac2ffc325e4beef76d1a621dff56b37328ac0640922594c9531a9ae0e63403
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release files / jsonschema_changelog-0.1.5-py3-none-any.whl

Download URL jsonschema_changelog-0.1.5-py3-none-any.whl
Size 5.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dbff2b38a797b90573d19a7588eecd275ba1bb033c67812ddbc8e0ff0c3d84fe
BLAKE2b-256 checksum
How to use checksums
41ac875cc7c67d30ea9e24c7dca932a17aa661ac8ccceac2941da4852bb25672
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.5 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page