Skip to main content

Structural diff for two JSON files — see which values changed, by path, ignoring key order and whitespace. Zero dependencies.

Project description

jdelta

A structural diff for two JSON files. git diff and diff work on lines — so reformatting, reordered keys, or a changed indent drown the one value you actually care about in red-and-green noise. jdelta compares the data, not the text, and tells you exactly which values changed, addressed by path. Zero dependencies, no network.

pip install jdelta

$ jdelta before.json after.json

Added (2)
  + email         "alice@corp.com"
  + user.tags[2]  "d"

Removed (1)
  - legacyId      1001

Changed (3)
  ~ user.age      30  31
  ~ user.role     "viewer"  "admin"
  ~ user.tags[1]  "b"  "c"

+2  -1  ~3

This is the Python build. A behavior-equivalent Node build is on npm: npx jdelta (https://github.com/jjdoor/jdelta).

Why

You're reviewing a config change, an API-response snapshot, a tsconfig, a locale file — and the diff is unreadable because someone ran a formatter or the serializer reordered keys. You don't care that line 40 moved to line 12; you care that auth.required flipped to false. jdelta ignores key order and whitespace entirely and reports the actual value-level delta by path.

Usage

jdelta old.json new.json            # human-readable, grouped by added/removed/changed
jdelta old.json new.json --json     # machine-readable
jdelta old.json new.json --quiet    # just the +a -r ~c summary line
jdelta old.json new.json --exit-code  # exit 1 if they differ (CI gate)

Options

Flag Effect
--json Emit { added, removed, changed, summary } as JSON
--quiet Print only a one-line summary (+a -r ~c, or no differences)
--exit-code Exit 1 when the files differ (for CI gates)
-v, --version Print version
-h, --help Show help

How it reads the diff

  • Paths. Object keys use dot notation (user.profile.age); array elements use index notation (items[2].price). Keys that aren't plain identifiers — containing dots, spaces or hyphens, or starting with a digit — fall back to quoted brackets: ["order-id"], ["123"].
  • Added / Removed / Changed. A key present on only one side is added or removed; a key on both with a different value is changed. A type change (numberstring, objectarray) is reported as a single changed entry tagged with the kinds — not as an add + remove.
  • Arrays are compared by index. xs[2] is compared to xs[2]; a length change shows up as added/removed trailing elements. (Inserting at the front of an array therefore reads as "everything shifted" — index diffing is simple and predictable rather than guessing at moves.)
  • Numbers are compared by value (1 and 1.0 are equal). Two caveats follow from how each runtime parses JSON numbers:
    • Float display. Floats are rendered by each runtime's native serializer, so an integral float can show as 1 (Node) or 1.0 (Python), and exotic floats (e.g. 1e-7) may differ in formatting. The detected change is the same.
    • Large integers. JavaScript has no bigint in JSON, so the Node build parses every number as an IEEE-754 double: integers beyond ±2^53 (snowflake IDs, int64 database keys) lose precision and can compare equal when they aren't — so the Node build may miss a change to such a value (and --exit-code won't fire). The Python build keeps integer precision exactly — prefer it for large-integer data.
  • Long values are abbreviated in the human view (truncated with past ~72 characters). --json output is never truncated.

--json shape

{
  "added":   [{ "path": "email", "value": "alice@corp.com" }],
  "removed": [{ "path": "legacyId", "value": 1001 }],
  "changed": [{ "path": "user.age", "from": 30, "to": 31 }],
  "summary": { "added": 1, "removed": 1, "changed": 1, "total": 3 }
}

Exit codes

Code Meaning
0 success (default — even when the files differ)
1 files differ and --exit-code was passed
2 error (bad args, unreadable file, invalid JSON)

By default jdelta is a viewer and exits 0; add --exit-code to make it a gate (the git diff --exit-code convention).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jdelta-0.1.0.tar.gz (10.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jdelta-0.1.0-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file jdelta-0.1.0.tar.gz.

File metadata

  • Download URL: jdelta-0.1.0.tar.gz
  • Upload date:
  • Size: 10.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for jdelta-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a91f1eaaf9e4e17c5a30f206c715a4edb06f562dcdb6af3adebd77678ea7961a
MD5 e642b2c627f14cae6cab3b93493bde64
BLAKE2b-256 45ac542e74aa990252f7e5df2c460a044fa8296588efee6049dd510838dbdc33

See more details on using hashes here.

File details

Details for the file jdelta-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: jdelta-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for jdelta-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e2593b897c66401308c72b30853e4cc85d2ca53cc232754cf73df1ddc12c6a91
MD5 4117bea2b119fd44366ba12c1fd1eddf
BLAKE2b-256 0d88cd9aecebd154ddd4dd3f8331957975962e9f76d89c60585d0f2a5bfdc86c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page