JSON Diff / Compare

Compare two JSON objects side-by-side to find differences.

Diff Result

About JSON Diff: comparing documents by structure, not by text

Comparing two JSON files as plain text produces noise. Key order, indentation, trailing whitespace and number formatting all show up as changes even when the data is identical. This tool parses both sides into objects first and compares the parsed structures, so the result reflects what a program consuming the JSON would actually see.

Under the hood it uses the diffJson function from the jsdiff library. Each side is normalised (object keys sorted alphabetically, then pretty-printed with two-space indentation) and the two normalised texts are compared line by line. Lines present only in the right-hand document are shown in green; lines present only in the left-hand document are shown in red with a strikethrough. Everything runs in your browser, so internal API responses and audit records never leave your machine.

What counts as a difference

LeftRightReported?Why
{"a": 1, "b": 2}{"b": 2, "a": 1}NoObject members are unordered (RFC 8259), and keys are sorted before comparing.
1, 1.0, 1e01NoAll three parse to the same number.
"1"1YesA string and a number are different types even when they look alike.
{"a": null}{}YesAn explicit null and a missing key are different things, and most APIs treat them differently too.
[1, 2, 3][3, 2, 1]YesArrays are ordered.
true"true"YesBoolean versus string.
90071992547409939007199254740992NoJavaScript numbers are 64-bit floats. Integers above 2^53 lose precision, so both parse to the same value. Send large IDs as strings.

How to read the result

There is one output pane rather than a side-by-side view. A changed value appears as a red line (the old value) followed by a green line (the new one). Because the comparison works on pretty-printed lines, inserting one element in the middle of an array produces a single green line and the elements after it stay unmarked. A change deep inside a nested object marks only the affected line, with the surrounding structure kept for context.

Whitespace inside string values does count: "New Delhi" and "New Delhi" (two spaces) are different strings, and so are "Active" and "active". For a case-insensitive or whitespace-insensitive comparison, normalise the values before pasting.

Everything lights up red and green? Check the syntax first

If either side fails to parse as JSON, the tool silently falls back to a plain line-by-line text diff of the raw input, and key order and formatting suddenly matter again. A trailing comma, a single-quoted string or a comment is enough to trigger this. Paste each side into the JSON formatter to get the exact position of the error. An empty side is treated as an empty object.

Diff, JSON Patch and JSON Merge Patch

This page shows a human-readable diff. When a machine needs to apply the change, two standard formats exist. JSON Patch (RFC 6902) is an array of operations (add, remove, replace, move, copy, test) whose paths use JSON Pointer syntax (RFC 6901), such as /users/0/email. JSON Merge Patch (RFC 7396) is simpler: you send a partial document, and a key set to null means delete. Kubernetes accepts both through kubectl patch --type json and --type merge, and many REST APIs implement HTTP PATCH with one of them.

// JSON Patch (RFC 6902)
[{ "op": "replace", "path": "/status", "value": "active" },
 { "op": "remove",  "path": "/legacyId" }]

// JSON Merge Patch (RFC 7396) with the same effect
{ "status": "active", "legacyId": null }

Command-line equivalents

The same idea (normalise, then diff) works in a terminal. Sorting keys with jq -S is the step most people forget:

diff <(jq -S . a.json) <(jq -S . b.json)        # bash or zsh: sort keys, then diff
jq -S . a.json > a.sorted.json                  # or write the sorted copy first
python3 -m json.tool --sort-keys a.json a.sorted.json
git diff --no-index a.sorted.json b.sorted.json # coloured diff outside a repository
jq 'del(.timestamp, .requestId)' a.json        # strip volatile fields before comparing
jq '.items |= sort_by(.id)' a.json             # make array order deterministic

Getting a clean comparison

  • Remove volatile fields first. Timestamps, request IDs, ETags and pagination cursors change on every call and hide the differences you care about.
  • Sort arrays by a stable key. If an API does not guarantee order, sort by id on both sides so a reordering is not reported as a rewrite.
  • Convert other formats first. YAML manifests and CSV exports can be turned into JSON with the YAML converter and the CSV converter, then compared here.
  • Watch the number types. A field that was "42" in one release and 42 in the next is a breaking change for strictly typed clients even though the value looks the same.

How to use

  1. Paste the original JSON into the left box and the modified JSON into the right box.
  2. The comparison runs automatically as you type; there is no compare button.
  3. Green lines exist only in the right-hand document; red, struck-through lines exist only in the left-hand one. Unchanged lines are shown for context.
  4. If the whole document is highlighted, one side is probably not valid JSON. Validate it with the JSON formatter and paste it back.
  5. Object key order and indentation are ignored automatically, so there is no need to format either side first.

Common use cases

  • Confirming that a refactored endpoint returns the same response body as the version it replaces.
  • Comparing the configuration JSON of two environments (staging and production) to find drift.
  • Reviewing a Terraform plan or CloudFormation template exported as JSON before applying it.
  • Checking what changed in package-lock.json or tsconfig.json between two branches.
  • Comparing analytics or webhook payloads emitted by two versions of a service.
  • Verifying that a database export matches a known-good snapshot after a migration.

Frequently asked questions

Does the diff care about object key order?

No. JSON objects are unordered by specification, so keys are sorted before comparison and two objects with the same members in a different order are reported as identical.

Does the diff care about array order?

Yes. Arrays are ordered, so [1, 2, 3] and [3, 2, 1] are different. If order is irrelevant for your data, sort both arrays by a stable key before pasting, for example with jq sort_by(.id).

Why are two different 19-digit IDs reported as identical?

JavaScript parses JSON numbers into 64-bit floating point values, which cannot represent every integer above 2 to the power 53 (about 9 quadrillion). Two large IDs that round to the same float compare as equal. APIs should send such IDs as strings, and the tool then compares them correctly.

Are 1 and 1.0 treated as the same value?

Yes. Both parse to the same number, as does 1e0. A string "1" is different from the number 1, however, because the types differ.

What happens if one side is not valid JSON?

The tool falls back to a plain text diff of the raw input without showing an error, which usually makes most of the document light up. Validate both sides with the JSON formatter to find the syntax problem.

How large a document can I compare?

The comparison runs in your browser tab, so the limit is browser memory and patience. Typical API responses and configuration files are handled instantly. For very large exports, the jq and diff commands above are more practical.

Can this tool produce a JSON Patch I can apply?

No. It shows a human-readable diff only. Libraries such as fast-json-patch (JavaScript) or jsonpatch (Python) can generate an RFC 6902 patch from two documents.

Can I ignore certain keys, such as timestamps?

Not inside the tool. Remove them on both sides first, for example with jq del(.timestamp), and then paste the results here.

Advertisement