{"id":29790237,"url":"https://github.com/andrew/json-schema-diff","last_synced_at":"2025-08-02T05:04:01.103Z","repository":{"id":306561866,"uuid":"1026619306","full_name":"andrew/json-schema-diff","owner":"andrew","description":"Semantic diff for JSON files using JSON Schema metadata","archived":false,"fork":false,"pushed_at":"2025-07-26T10:50:01.000Z","size":49,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-26T13:42:20.913Z","etag":null,"topics":["diff","json","json-schema","ruby","ruby-gem"],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/json-schema-diff","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrew.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"andrew","ko_fi":"andrewnez","polar":"andrew","buy_me_a_coffee":"andrewnez"}},"created_at":"2025-07-26T08:55:59.000Z","updated_at":"2025-07-26T11:52:28.000Z","dependencies_parsed_at":"2025-07-26T13:42:26.691Z","dependency_job_id":"b384cd26-b0c2-42d9-ba1b-1b31e7425e0e","html_url":"https://github.com/andrew/json-schema-diff","commit_stats":null,"previous_names":["andrew/json-schema-diff"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/andrew/json-schema-diff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrew%2Fjson-schema-diff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrew%2Fjson-schema-diff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrew%2Fjson-schema-diff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrew%2Fjson-schema-diff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrew","download_url":"https://codeload.github.com/andrew/json-schema-diff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrew%2Fjson-schema-diff/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267442442,"owners_count":24087798,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diff","json","json-schema","ruby","ruby-gem"],"created_at":"2025-07-28T00:00:37.529Z","updated_at":"2025-07-28T00:00:39.253Z","avatar_url":"https://github.com/andrew.png","language":"Ruby","funding_links":["https://github.com/sponsors/andrew","https://ko-fi.com/andrewnez","https://polar.sh/andrew","https://buymeacoffee.com/andrewnez"],"categories":[],"sub_categories":[],"readme":"# JSON Schema Diff\n\nA Ruby gem that performs semantic diffs between JSON files, using JSON Schema to guide and annotate the diff output with type information, field metadata, and structured change detection.\n\n[![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.2-red.svg)](https://www.ruby-lang.org/)\n[![Gem Version](https://badge.fury.io/rb/json-schema-diff.svg)](https://rubygems.org/gems/json-schema-diff)\n[![Documentation](https://img.shields.io/badge/docs-rubydoc.info-blue.svg)](https://rubydoc.info/gems/json-schema-diff)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nPerfect for comparing structured CLI output from security tools like zizmor and capslock across versions to highlight when security issues have been introduced or resolved.\n\n## Features\n\n- **Schema-guided diffing** - Uses JSON Schema metadata to provide context for changes\n- **Multiple output formats** - Pretty colorized output for humans, JSON for machines\n- **Smart field filtering** - Automatically detects and can ignore noisy fields (timestamps, UUIDs)\n- **Read-only field support** - Respects `readOnly` schema properties\n- **Nested object and array support** - Handles complex JSON structures\n- **Custom field ignoring** - Ignore specific fields by path\n- **Type and format information** - Shows field types, formats, and enum values from schema\n- **Change categorization** - Clearly identifies additions, removals, and modifications\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'json-schema-diff'\n```\n\nAnd then execute:\n\n```bash\nbundle install\n```\n\nOr install it yourself as:\n\n```bash\ngem install json-schema-diff\n```\n\n## Usage\n\n### Basic Usage\n\n```bash\njson-schema-diff schema.json old.json new.json\n```\n\n### Output Formats\n\n```bash\n# Pretty colorized output (default)\njson-schema-diff --format pretty schema.json old.json new.json\n\n# Machine-readable JSON output\njson-schema-diff --format json schema.json old.json new.json\n\n# Disable colors\njson-schema-diff --no-color schema.json old.json new.json\n```\n\n### Validation Options\n\n```bash\n# Enable JSON validation against schema (helps catch data format errors)\njson-schema-diff --validate-json schema.json old.json new.json\n\n# Disable schema format validation (for malformed schemas)\njson-schema-diff --no-validate schema.json old.json new.json\n\n# Both validation options\njson-schema-diff --validate-json --validate schema.json old.json new.json\n```\n\n### Ignoring Fields\n\n```bash\n# Ignore specific fields (comma-separated)\njson-schema-diff --ignore-fields timestamp,scan_id,duration_ms schema.json old.json new.json\n```\n\n### CLI Options\n\n```bash\n# Show help\njson-schema-diff --help\n\n# Show version\njson-schema-diff --version\n\n# All options\njson-schema-diff [OPTIONS] SCHEMA OLD_JSON NEW_JSON\n\nOptions:\n  -f, --format FORMAT          Output format (pretty, json)\n  -i, --ignore-fields FIELDS   Comma-separated list of field paths to ignore\n      --[no-]color             Enable/disable colored output (default: enabled)\n      --[no-]validate          Enable/disable JSON Schema format validation (default: enabled)\n      --[no-]validate-json     Enable/disable JSON validation against schema (default: disabled)\n  -h, --help                   Show help message\n  -v, --version                Show version\n```\n\n### Example Output\n\n```\nJSON Schema Diff Results\n==================================================\n\nADDITIONS (1):\n\n  issues[3] (object)\n    + Added: {\"id\":\"ZIZ004\",\"severity\":\"critical\",\"category\":\"crypto\",...}\n\nREMOVALS (1):\n\n  issues[2] (object)\n    Title: Security Issue\n    + Removed: {\"id\":\"ZIZ003\",\"severity\":\"medium\",\"category\":\"misc\",...}\n\nMODIFICATIONS (2):\n\n  metadata.version (string)\n    Title: Tool Version\n    - Old: \"1.2.0\"\n    + New: \"1.3.0\"\n\n  summary.by_severity.critical (integer)\n    Title: Critical Issues\n    - Old: 1\n    + New: 2\n\nSUMMARY:\nTotal changes: 4\nNoisy fields: 2\n```\n\n### Ruby API\n\n```ruby\nrequire 'json/schema/diff'\n\n# Parse schema\nschema = Json::Schema::Diff::SchemaParser.new('schema.json')\n\n# Create comparer with optional ignore fields\ncomparer = Json::Schema::Diff::Comparer.new(schema, ['timestamp', 'scan_id'])\n\n# Load and compare JSON files\nold_json = JSON.parse(File.read('old.json'))\nnew_json = JSON.parse(File.read('new.json'))\n\nchanges = comparer.compare(old_json, new_json)\n\n# Format results\nformatter = Json::Schema::Diff::Formatter.new('pretty', true)\nputs formatter.format(changes)\n```\n\n## Schema Features\n\n### Supported JSON Schema Properties\n\n- **type** - Field data type (string, integer, object, array, etc.)\n- **title** - Human-readable field name\n- **description** - Field description\n- **format** - Field format (date-time, uuid, email, etc.)\n- **enum** - Allowed values for the field\n- **readOnly** - Fields marked as read-only are ignored in diffs\n\n### Noisy Field Detection\n\nThe gem automatically detects potentially noisy fields based on:\n\n- **Format hints**: `date-time`, `date`, `time`, `uuid` formats\n- **Value patterns**: UUID strings, ISO timestamp strings\n- **Schema annotations**: Fields marked as `readOnly`\n\n### Example Schema\n\n```json\n{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"Security Report Schema\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"metadata\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tool\": {\n          \"type\": \"string\",\n          \"title\": \"Tool Name\",\n          \"enum\": [\"zizmor\", \"capslock\", \"semgrep\"]\n        },\n        \"timestamp\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"readOnly\": true\n        }\n      }\n    },\n    \"issues\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"severity\": {\n            \"type\": \"string\",\n            \"enum\": [\"critical\", \"high\", \"medium\", \"low\"]\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## Use Cases\n\n### Security Tool Comparison\n\nCompare security scan results across tool versions:\n\n```bash\n# Compare zizmor audit results (official schema)\n# See: https://github.com/zizmorcore/zizmor\njson-schema-diff examples/zizmor/zizmor.schema.json zizmor-v0.1.0.json zizmor-v0.2.0.json\n```\n\n**Example Output:**\n```\nJSON Schema Diff Results\n==================================================\n\nADDITIONS (1):\n\n  [2]\n    + Added: {\"ident\":\"hardcoded-credentials\",\"desc\":\"Hardcoded credentials detected\",...}\n\nMODIFICATIONS (2):\n\n  [1].determinations.confidence\n    - Old: \"Medium\"\n    + New: \"High\"\n\n  [1].determinations.severity  \n    - Old: \"Medium\"\n    + New: \"High\"\n\nSUMMARY:\nTotal changes: 3\n```\n\n```bash\n# Compare capslock capability analysis  \n# See: https://github.com/google/capslock\njson-schema-diff examples/capslock/capslock.schema.json capslock-v0.5.0.json capslock-v0.6.0.json\n```\n\n**Example Output:**\n```\nJSON Schema Diff Results\n==================================================\n\nADDITIONS (3):\n\n  capability_info[2]\n    + Added: {\"package_name\":\"github.com/example/myapp/crypto\",\"capability\":\"CAPABILITY_ARBITRARY_EXECUTION\",...}\n\n  module_info[2]  \n    + Added: {\"path\":\"github.com/suspicious/lib\",\"version\":\"v1.2.3\"}\n\n  package_info[2]\n    + Added: {\"path\":\"github.com/example/myapp/crypto\",\"ignored_files\":[]}\n\nMODIFICATIONS (2):\n\n  module_info[0].version\n    - Old: \"v1.0.0\"\n    + New: \"v1.1.0\"\n\n  module_info[1].version\n    - Old: \"v1.8.0\" \n    + New: \"v1.8.1\"\n\nSUMMARY:\nTotal changes: 5\n```\n\n### CI/CD Integration\n\nIntegrate into your CI pipeline to track security improvements:\n\n```bash\n#!/bin/bash\n# Run zizmor security scan\nzizmor --format json \u003e zizmor-current.json\n\n# Compare with previous scan using official schema\nif [ -f zizmor-previous.json ]; then\n  json-schema-diff examples/zizmor/zizmor.schema.json zizmor-previous.json zizmor-current.json --format json \u003e security-diff.json\nfi\n\n# Archive current scan for next comparison\ncp zizmor-current.json zizmor-previous.json\n\n# Run capslock capability analysis\ncapslock -output json \u003e capslock-current.json\nif [ -f capslock-previous.json ]; then\n  json-schema-diff examples/capslock/capslock.schema.json capslock-previous.json capslock-current.json --format json \u003e capability-diff.json\nfi\ncp capslock-current.json capslock-previous.json\n```\n\n**Example JSON Output for Automation:**\n```json\n[\n  {\n    \"path\": \"[1].determinations.severity\",\n    \"change_type\": \"modification\", \n    \"old_value\": \"Medium\",\n    \"new_value\": \"High\",\n    \"field_info\": {},\n    \"is_noisy\": false\n  },\n  {\n    \"path\": \"[2]\",\n    \"change_type\": \"addition\",\n    \"old_value\": null,\n    \"new_value\": {\n      \"ident\": \"hardcoded-credentials\",\n      \"desc\": \"Hardcoded credentials detected\",\n      \"determinations\": {\n        \"confidence\": \"High\",\n        \"severity\": \"High\"\n      }\n    },\n    \"field_info\": {},\n    \"is_noisy\": false\n  }\n]\n```\n\n### Configuration Monitoring\n\nTrack changes in complex configuration files using SchemaStore schemas:\n\n```bash\n# Monitor package.json changes\ncurl -s https://json.schemastore.org/package.json \u003e package.schema.json\njson-schema-diff --ignore-fields version package.schema.json old-package.json new-package.json\n```\n\n**Example Output:**\n```\nJSON Schema Diff Results\n==================================================\n\nADDITIONS (1):\n\n  dependencies.lodash (string)\n    Title: Dependency\n    + Added: \"^4.17.21\"\n\nMODIFICATIONS (1):\n\n  scripts.test (string)\n    Title: Script Command\n    - Old: \"jest\"\n    + New: \"jest --coverage\"\n\nSUMMARY:\nTotal changes: 2\n```\n\n```bash\n# Track GitHub Actions workflow changes\ncurl -s https://json.schemastore.org/github-workflow.json \u003e workflow.schema.json  \njson-schema-diff workflow.schema.json old-workflow.json new-workflow.json\n\n# Monitor Docker Compose changes\ncurl -s https://json.schemastore.org/docker-compose.yml \u003e compose.schema.json\njson-schema-diff compose.schema.json old-compose.json new-compose.json\n```\n\n### Development Workflow Analysis\n\nCompare development tool outputs with proper schema context:\n\n```bash\n# ESLint configuration changes\ncurl -s https://json.schemastore.org/eslintrc.json \u003e eslint.schema.json\njson-schema-diff eslint.schema.json old-eslintrc.json new-eslintrc.json\n\n# TypeScript configuration tracking  \ncurl -s https://json.schemastore.org/tsconfig.json \u003e tsconfig.schema.json\njson-schema-diff tsconfig.schema.json old-tsconfig.json new-tsconfig.json\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then:\n\n```bash\n# Run tests\nrake test\n\n# Run with example files\nbundle exec exe/json-schema-diff examples/security-report.schema.json examples/old-report.json examples/new-report.json\n\n# Install locally\nbundle exec rake install\n```\n\n## Examples\n\nThe `examples/` directory contains organized examples for different security tools:\n\n### Tool-Specific Examples\n\n- **`examples/zizmor/`** - [Zizmor](https://github.com/zizmorcore/zizmor) GitHub Actions security auditor\n  - `zizmor.schema.json` - Official zizmor JSON output schema (v1)  \n  - `zizmor-v0.1.0.json` / `zizmor-v0.2.0.json` - Sample audit reports across versions\n\n- **`examples/capslock/`** - [Capslock](https://github.com/google/capslock) Go capability analysis\n  - `capslock.schema.json` - Google's Capslock capability analysis schema\n  - `capslock-v0.5.0.json` / `capslock-v0.6.0.json` - Sample capability reports across versions\n\n- **`examples/generic/`** - Generic security tool template\n  - `security-report.schema.json` - Generic security analysis reports schema\n  - `report-v1.2.0.json` / `report-v1.3.0.json` - Sample security reports\n\n### Try the Examples\n\n```bash\n# Zizmor security audit comparison (official schema)\njson-schema-diff examples/zizmor/zizmor.schema.json examples/zizmor/zizmor-v0.1.0.json examples/zizmor/zizmor-v0.2.0.json\n\n# Capslock capability analysis\njson-schema-diff examples/capslock/capslock.schema.json examples/capslock/capslock-v0.5.0.json examples/capslock/capslock-v0.6.0.json\n\n# Generic security tool comparison  \njson-schema-diff examples/generic/security-report.schema.json examples/generic/report-v1.2.0.json examples/generic/report-v1.3.0.json\n```\n\n### Using Existing Schemas\n\nThe gem works with any valid JSON Schema. You can use schemas from:\n\n- **[SchemaStore.org](https://www.schemastore.org/)** - Hundreds of schemas for popular tools and configurations\n- **Tool documentation** - Many CLI tools provide JSON schemas for their output\n- **Custom schemas** - Create your own schemas for proprietary formats\n\nFor example, with SchemaStore schemas:\n\n```bash\n# Compare GitHub Actions workflows\ncurl -o github-workflow.schema.json https://json.schemastore.org/github-workflow.json\njson-schema-diff github-workflow.schema.json old-workflow.yml new-workflow.yml\n\n# Compare package.json files  \ncurl -o package.schema.json https://json.schemastore.org/package.json\njson-schema-diff package.schema.json old-package.json new-package.json\n\n# Compare Docker Compose files\ncurl -o compose.schema.json https://json.schemastore.org/docker-compose.yml\njson-schema-diff compose.schema.json old-compose.yml new-compose.yml\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at \u003chttps://github.com/andrew/json-schema-diff\u003e.\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Make your changes\n4. Add tests for your changes\n5. Ensure all tests pass (`rake test`)\n6. Commit your changes (`git commit -am 'Add some feature'`)\n7. Push to the branch (`git push origin my-new-feature`)\n8. Create new Pull Request\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.\n\n## Security\n\nFor security issues, please see our [Security Policy](SECURITY.md).\n\n## License\n\nThis gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes and releases.\n\n## Code of Conduct\n\nEveryone interacting in the json-schema-diff project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrew%2Fjson-schema-diff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrew%2Fjson-schema-diff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrew%2Fjson-schema-diff/lists"}