Skip to content
Tools

JSON Compare

Compare two JSON documents side-by-side and instantly identify added, removed and modified values. Everything runs locally in your browser.

Visible pane

Paste or upload two JSON documents to compare them.

Left:Empty

Right:Empty

Everything happens locally in your browser. Your JSON is never uploaded.

What is JSON compare?

A JSON compare tool takes two JSON documents and tells you precisely how they differ: which keys appeared, which disappeared, which values changed, and where in the structure each of those things happened.

The important word is data. It does not compare the two files as text. It parses both, then walks the resulting structures together, matching key against key and item against item. That is why re-indenting a file or reordering its properties produces no differences at all — nothing about the data changed, only its spelling.

The result is shown side by side, with each row aligned against its counterpart and marked according to what happened to it:

Two versions of the same response
"id": 1042"id": 1042
"city": "London""city": "Cambridge"
"legacyExport": true
"hasMore": false

Four rows, four verdicts: one unchanged, one modified, one removed, one added. Reading that takes a second. Finding the same four facts by scrolling two documents in two windows takes considerably longer, and is much easier to get wrong.

Why compare JSON?

Because “what changed?” is one of the most common questions in software, and JSON is the format most of the answers are written in. Comparing by hand does not scale past a screenful, and comparing as text answers a subtly different question:

  • Formatting stops being noise. A file that was re-indented, or written by a different serialiser, shows zero differences instead of hundreds. Only real changes survive.
  • You get a count, not an impression. Twelve added keys, five removed, eighteen modified. That is something you can check against what the change was supposed to do.
  • Every difference has an address. Each one carries its JSON path, so $.users[2].address.city goes straight into a bug report, a test assertion, or a JSONPath tester if you want to pull the same field out of a third document.
  • Type changes surface. An id that quietly became a string, or a number that arrived as null, is exactly the kind of change that passes review and breaks a client. It is reported explicitly here.
  • Minified documents stop being opaque. A line diff of two single-line files tells you only that line one differs. A structural comparison pinpoints the character that moved.
  • Size stops mattering. Identical branches are skipped rather than walked, so most of a large pair of documents costs nothing to compare.

Features

Everything below runs in your browser. There is no upload step, no queue and no account.

Side-by-side diff

Both documents are drawn from a single merged tree, so the two columns cannot drift out of alignment: every row shows the same position in both documents, and scrolling and expanding move both sides together by construction rather than by synchronisation. Added rows are green, removed rows red, modified rows amber, and each carries a +, or ~ marker so the status does not depend on colour alone.

Everything it detects

Added keys, removed keys, modified values, type changes, array differences, object differences and nested differences at any depth. A key whose value is an entire object counts as one addition, not one per field inside it — the summary counts changes, not lines.

Comparison options

Compare by value, or by structure alone when only the shape matters. Ignore case in keys and string values, ignore leading, trailing and repeated whitespace, and ignore array order to match items by content instead of position. Formatting and key order are always ignored, because the comparison never sees the text.

Navigation and search

Step through the differences one at a time with previous and next; each jump opens whatever branches are needed and centres the result. Search runs across both documents at once and can be limited to keys or to values. “Only differences” hides every identical row; “Expand changed” opens precisely the branches that contain one.

JSON paths

Select any row to see its path in $.users[2].address.cityform, ready to copy, along with buttons to copy that row’s value from either side. Keys that are not valid identifiers are bracketed and quoted, so what you copy is a valid expression rather than an approximate one.

Summary and statistics

Added, removed, modified and total differences at a glance, alongside separate statistics for each document: characters, lines, objects, arrays, keys, maximum depth and size.

Export

Copy or download the full list of differences as a JSON report — every change with its path, its status and both values, plus the options the comparison ran under, so the result is reproducible.

Files, swapping and fullscreen

Upload a file into either side or drop one onto its panel; the filename becomes that side’s label. Swap the two documents with one press when you have loaded them the wrong way round, and go fullscreen when the comparison deserves the whole window.

How JSON comparison works

  1. 1. Both documents are parsed. Comparison operates on data, so both sides have to be valid JSON first. If either fails, the tool reports which side, what went wrong and exactly where, and waits — comparing against a document that could not be read would produce nonsense. For a document with several problems in it, the JSON validator lists them all in one pass.
  2. 2. The two structures are walked together. Starting at the root, each value is matched with its counterpart. Objects are matched by key name, which is why property order is irrelevant. Arrays are matched by position, unless you have asked for them to be matched by content.
  3. 3. Identical branches are skipped. When two subtrees are equal, the comparison records that and stops descending. This is what keeps large documents affordable: the parts that did not change cost one comparison each, not one per field.
  4. 4. Each difference is classified. A key present on only one side is added or removed. A key on both whose values differ is modified, and if the two values are of different JSON types that is recorded as a type change. Containers themselves stay neutral — what changed is inside them.
  5. 5. The results are rolled up.A final pass marks every branch that contains a difference, counts the additions, removals and modifications, and puts the changes in document order so that “next difference” walks the document the way you read it.

One consequence is worth knowing. Because objects are matched by name, renaming a key is reported as a removal plus an addition rather than as a rename — the comparison cannot know that city became town rather than one field being dropped and another added. The same is true of an array item moved a long way while also being edited.

When should you compare JSON?

Whenever two versions of the same data exist and the difference between them matters more than either version on its own.

API responses

Capture a response before a deployment and after it, and see exactly what the change did to the payload. New fields, dropped fields and quietly altered types all surface at once — including the ones nobody meant to change.

Configuration files

Put staging beside production and read the differences rather than trusting that they are what you remember. This is where a structural comparison earns its keep: config files are edited by many hands and reformatted by many tools.

Version comparison

Compare two releases of a manifest, a schema or a lockfile. Because formatting is ignored, the only things reported are the ones that would actually change behaviour.

Database exports

Diff a record before and after a migration to confirm the transformation did what it claimed — and only what it claimed. The summary counts turn "looks about right" into a number you can check.

Debugging

When one environment works and another does not, the difference is usually in the data. Compare the two payloads and the cause is often a single row: a string where a number was expected, or a field that arrived null.

Testing

Compare an actual response against the fixture it was supposed to match. The JSON path of each difference drops straight into an assertion, and the exported report attaches to a bug ticket as evidence.

JSON compare vs JSON diff

The two terms get used interchangeably, but they describe different operations, and the difference shows up the moment a file gets reformatted.

A diff is textual. It is what git diff and every side-by-side merge tool does: compare two files line by line and report which lines were inserted, deleted or changed. It knows nothing about JSON. It would behave identically on a shopping list.

A compare is structural. Both documents are parsed and the resulting data is compared. It knows that objects are unordered, that whitespace between tokens is meaningless, and that 1 and "1" are different types.

Take one document written two ways:

Version A
{"name":"Ada","id":1042}
Version B — reformatted, keys reordered, same data
{  "id": 1042,  "name": "Ada"}

A line diff reports every line as changed. A structural comparison reports nothing at all, which is the correct answer: no data changed. Now the reverse — a single edit inside a minified document:

{"users":[{"id":1,"active":true},{"id":2,"active":true}]}
{"users":[{"id":1,"active":true},{"id":2,"active":false}]}

A line diff says “line 1 changed”, which is true and useless. A structural comparison says $.users[1].active changed from true to false.

Neither is better in general; they answer different questions. Use a line-by-line text diff when the file itself is the artefact — when you care about the commit, the formatting or the line numbers. Use a structural comparison when the data is the artefact and the file is just how it happened to be written down.

Common use cases

A few patterns come up often enough to be worth naming, along with the settings that suit them.

Checking that a refactor changed nothing

Capture the output before and after, and compare with the default settings. The answer you want is zero differences. Anything else is a list of things to explain.

Reviewing an environment drift

Put two configuration files side by side and turn on “Only differences”. What remains is the entire delta between the environments, usually short enough to read in one screen.

Validating a schema change

Switch to compare by structure. Values are ignored and only the shape is examined, which answers “does this response still have the fields and types my client expects?” without the noise of different data.

Comparing unordered collections

Lists of tags, permissions or regions often carry no meaningful order. Turn on “Ignore array order” and items are matched by content, so a re-serialised list stops reporting a difference for every position that shifted.

Comparing data from inconsistent sources

When two systems disagree about capitalisation or padding, “Ignore case” and “Ignore whitespace” strip that layer away so the differences that remain are differences of substance.

Attaching evidence to a bug report

Download the differences. The report lists every change with its path and both values, along with the options used, so whoever reads it can reproduce exactly the comparison you ran. If the ticket wants something that reads like a code review, the JSON diffruns the same comparison and prints it in Git’s unified format instead.

Frequently asked questions

Is this JSON compare tool free?

Yes. The side-by-side diff, every comparison option, the summary counts, search, JSON paths, uploads and downloads are all free, with no account, no usage cap and no paid tier. Nothing is held back.

Is my JSON uploaded anywhere?

No. Both documents are parsed and compared by JavaScript running in your own browser. Neither one is sent over the network, stored or logged. You can confirm this by watching your browser's network panel, or by disconnecting from the internet after the page loads — the comparison keeps working.

Can I compare large JSON files?

Yes. Documents up to roughly 20 MB each are supported. Files over about 120 KB are parsed in a background Web Worker so the page never freezes, the comparison skips identical branches wholesale rather than walking them, and the result view only renders the rows currently on screen. A pair of multi-megabyte files compares in well under a second on ordinary hardware.

Does it ignore formatting and indentation?

Always. The comparison works on the parsed data, not the text, so indentation, line breaks, spacing and the order properties were written in can never register as differences. Two documents that a parser reads identically are reported as identical, however differently they are laid out.

Does key order count as a difference?

No. JSON objects are unordered by definition, so {"a":1,"b":2} and {"b":2,"a":1} are the same document and are reported as identical. Array order is different — arrays are ordered, so a reordered array is a real difference by default. Turn on "Ignore array order" if the order genuinely does not matter to you.

Can I compare nested objects?

Yes, to any depth. The comparison descends through every level and reports the difference at the exact position it occurs, so a value that changed six levels down is shown as one difference at $.users[2].address.city rather than as a wholesale change to $.users. The parser and the comparison are both iterative, so nesting depth is limited by memory rather than by the JavaScript call stack.

How are arrays compared?

By position by default: the first item is compared with the first, the second with the second, and items with no counterpart at the end are reported as added or removed. That is the honest reading, since arrays are ordered. Turning on "Ignore array order" instead matches items by content, so a reordered list reads as unchanged — and an item that was both moved and edited still shows as a single modification rather than as a removal plus an addition.

What is the difference between JSON Compare and JSON Diff?

A text diff — what most tools mean by "diff" — compares two files line by line and shows which lines changed. A JSON compare parses both documents first and compares the data. The distinction matters: reformat a file and a text diff lights up from top to bottom while a JSON compare reports no differences at all, because none of the data changed. Conversely, a one-character edit deep in a minified single-line document is invisible to a line diff but is pinpointed exactly here.

What does compare by structure do?

It compares shape and types while ignoring what the scalars hold. Two API responses with the same keys, the same nesting and the same types match even if every number and string differs. It is the mode to use when you are checking that a response still conforms to the shape a client expects, rather than checking the data itself.

Can I upload JSON files?

Yes. Each side has its own upload button, and you can drag a .json file straight onto either panel. Files are read locally with the browser's FileReader API — the filename is picked up as that side's label so the comparison says which file is which. Files up to 20 MB are accepted.

What happens if one of my documents is invalid?

The comparison does not run, because there is nothing meaningful to compare a broken document against. Instead the status bar names which side failed, what went wrong, and the exact line and column, with a button that jumps the cursor there. Fix it and the comparison appears immediately.

Can I see only the differences?

Yes. Turn on "Only differences" and every identical row is hidden, leaving just the changes and the branches that lead to them. It is the fastest way to read a comparison of two large documents that are mostly the same. "Expand changed" does the gentler version: it opens exactly the branches containing a difference and leaves the rest collapsed.

Can I copy or export the differences?

Yes. Copy differences and Download differences both produce a JSON report listing every change with its path, its status and the values on each side, along with the summary counts and the options the comparison ran under. Individual rows can also be copied one at a time: the JSON path, the left value or the right value.

Why does a reordered array show so many differences?

Because arrays are ordered, and by default the tool compares them that way: moving one item to the front shifts every item after it, and each shifted position is a genuine difference in the data. If order carries no meaning in your document — a set of tags, say — turn on "Ignore array order" and the items are matched by content instead.

Does the comparison work offline?

Once the page has loaded, yes. All parsing and comparison is local, so you can disconnect and keep working. A connection is only needed to load the page in the first place.

Popular tools

↑ ↓NavigateOpenEscClose