Loading the JSON comparison…

Compare two JSON files by structure, not by text

A text diff of two JSON files reports the formatting and leaves you to find the meaning. A structural diff compares values at the same path, so what you see is what actually changed.

Why a text diff is the wrong tool

JSON has no canonical form. The same data can be written with two-space or four-space indent, with the keys in any order, with 1.0 where another producer wrote 1, and with a trailing newline or without one. None of that is a change to the data, and all of it is a change to the text. Run diff over two exports of the same record from two services and the output is mostly noise.

The opposite failure is quieter and worse. A real change — one property renamed deep inside the twelfth element of an array — is a handful of lines in a file of a hundred thousand, sitting beside a hundred lines of reformatting. It is there in the diff, and nobody sees it.

What a structural comparison does instead

Aligning arrays, which is the hard part

An array is the one place where "the same element" needs deciding. JSONParse offers three answers and lets you pick, because the right one depends on what the array means.

ModeHow elements are pairedUse it when
Smart alignmentBy an identity key (id, uuid, …) when every object in the array has one and the values are unique; otherwise by content, using a longest-common-subsequence alignment over structural fingerprints.The default. Lists of records, config blocks, anything where an element has an identity or where inserts and deletions happen.
By positionElement 0 against element 0, element 1 against element 1.Fixed-shape arrays such as coordinate pairs or matrix rows, where position *is* the meaning.
Ignore orderAs a multiset: equal elements pair up wherever they sit, and only genuine additions and removals are reported.Sets written as arrays — tags, permissions, feature lists — where order is an accident of serialisation.

With smart alignment, an element that only moved is reported as moved rather than as a removal and an unrelated addition. Turn that off if you want position changes ignored entirely.

A worked example

Two deployment manifests, one release apart:

{ "replicas": 3, "regions": ["eu-west-1", "us-east-1"], "retries": "3" }
{ "replicas": 5, "regions": ["ap-south-1", "eu-west-1", "us-east-1"], "retries": 3 }

A text diff calls both lines changed and leaves the reading to you. The structural comparison reports three things, each at its own address:

~ /replicas   3 → 5
+ /regions/0  "ap-south-1"
~ /retries    "3" → 3

The third line is the one that matters: retries went from a string to a number. That is a type change, it is the kind of thing that breaks a consumer at three in the morning, and in a text diff it looks exactly like the harmless ones.

Exporting the result

A comparison is worth more when it leaves the screen. Two exports are offered: an RFC 6902 JSON Patch, which is a list of operations that transform the first document into the second and can be applied by any patch library, and a change report, which is one line per difference with its pointer, suitable for a pull request comment or a ticket.

The patch is ordered so that it actually applies: within an array, removals are emitted by their original index in descending order, then insertions by their new index, then replacements. Moved elements are emitted as a removal and an insertion rather than as a move, because a move whose source index has already shifted is the classic way these patches go quietly wrong.

Size, and where it runs

Both documents are parsed into the same flat typed-array index the viewer uses, then merged into a single diff tree that the same virtualised renderer draws. Nothing is uploaded, and the comparison runs in a Web Worker, so the window stays responsive while two large files are aligned.

LimitValueWhat happens at the edge
Merged rows2,000,000The comparison stops and says it is incomplete rather than exhausting memory.
Document sizeBounded by available memoryBoth files are held at once, so budget for roughly twice what the viewer needs for one.
HTTP API body4 MB totalBoth documents together. Larger pairs belong in the browser, where they are never transmitted.

From a script or an agent

The same comparison is available at POST /api/diff and as the json_diff tool on the MCP server, so a CI job can fail a build on an unexpected schema change and an assistant can answer "what changed between these two payloads" without diffing text. See the API reference for the request shape.

curl -sS https://jsonparse.online/api/diff \
  -H 'content-type: application/json' \
  -d '{
        "left": "{\"replicas\":3}",
        "right": "{\"replicas\":5}",
        "options": { "output": "patch" }
      }'

Frequently asked questions

How is this different from running diff on two JSON files?

A text diff compares lines of characters, so reindenting a file or reordering its keys shows up as a change and a genuine change can be buried in that noise. This compares the parsed documents: values are matched by key and by path, numbers are compared by value, and formatting is invisible.

Does the order of keys in an object count as a change?

No. Object members are matched by name, so two documents whose keys appear in different orders compare as identical. JSON objects are unordered by definition and every parser is free to present them in any order.

What happens when an element is inserted into the middle of an array?

With the default smart alignment, the inserted element is reported as an addition and everything after it stays matched to its counterpart. Switch to positional comparison if you want index-for-index behaviour instead, which will mark the remainder of the array as changed.

Can I ignore case, whitespace or tiny numeric differences?

Yes. String values can be compared case-insensitively, with leading and trailing whitespace trimmed, or with repeated whitespace collapsed, and numbers can be given an absolute tolerance so that values within it compare as equal. Keys are always compared case-sensitively.

Are my files uploaded when I compare them?

No. Both files are read with the browser File API and compared in a Web Worker on your own machine, the same as the viewer. The HTTP API and the MCP server are the exception and receive whatever you send them, which is why the documents there are capped at 4 MB.

Can I apply the result to the first file?

Yes. Export the comparison as an RFC 6902 JSON Patch and apply it with any standard patch library; the operations are ordered so that applying them to the original document reproduces the changed one exactly.