Skip to content

Repository files navigation

json-shape-diff

Test Python 3.10+ License: MIT

Compare the structure of JSON payloads without printing their values.

json-shape-diff derives a compact shape from JSON or JSON Lines input and reports field, type, required-status, and array-item drift using JSON Pointer paths. Output is deterministic and suitable for local checks or CI.

Why use it?

Payload diffs often expose customer data, tokens, or large irrelevant values. This tool reports the contract-level change instead:

REMOVED           /user/displayName  string -> -
TYPE_CHANGED      /user/id           integer -> string
REQUIRED_CHANGED  /user/timezone     optional -> required

Values are never included in shape or diff output.

Install

Requires Python 3.10 or later and has no runtime dependencies.

python -m pip install .

For development:

python -m pip install --editable .

Usage

Inspect one payload:

json-shape-diff shape response.json

Compare a baseline with a new payload:

json-shape-diff diff baseline.json current.json

Read JSON Lines automatically from .jsonl or .ndjson files:

json-shape-diff shape events.jsonl --format json

Use - for standard input. Only one side of a diff can read from standard input:

curl -sS https://example.test/api | json-shape-diff diff baseline.json -

CI behavior

By default, diff exits with status 1 for any structural change. Select a different policy with --fail-on:

json-shape-diff diff baseline.json current.json --fail-on breaking
json-shape-diff diff baseline.json current.json --fail-on never

The breaking policy treats removed fields, type changes, and a change from optional to required as breaking. This is a practical heuristic, not a full compatibility proof; producer and consumer expectations can differ.

Exit code Meaning
0 No change matched the selected failure policy
1 Structural drift matched the selected failure policy
2 Invalid arguments, unreadable input, or invalid JSON

Shape model

  • JSON objects record property shapes and whether each property was present in every observed object.
  • Arrays merge the shapes of all their items. A heterogeneous array therefore has multiple possible types.
  • JSON Lines input merges all non-empty records.
  • Object keys use RFC 6901 JSON Pointer escaping in diff output.
  • Array item paths use *, for example /users/*/id.

Non-goals

  • This is not a JSON Schema validator or schema generator.
  • This is not a secret scanner. Use a dedicated tool such as Gitleaks before publishing sensitive repositories.
  • The tool does not infer semantic constraints, formats, ranges, or example values.

Development

python -m unittest discover -s tests -v
python -m compileall -q src tests

See CONTRIBUTING.md for the contribution workflow and SECURITY.md for private vulnerability reporting guidance.

About

Compare JSON and JSONL structures without exposing payload values.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages