Everything runs in your browser. We never see your JSON. How we prove it →
JSON Diff — Semantic JSON Compare
Paste two JSON documents. They are parsed before they are compared, so reordered keys stay quiet and real edits stand out.
How semantic JSON comparison works
A comparison that works on the raw characters will flag a reordered key as an edit, and RFC 8259 is explicit that it is not one: a JSON object is an unordered collection of name/value pairs, so `{"id":7,"plan":"pro"}` and `{"plan":"pro","id":7}` are the same document and this page reports nothing changed. Arrays get the opposite treatment: their elements are ordered by definition, so promoting an item from index 4 to index 0 is a genuine edit and is reported as one. Both sides are parsed into real values, then walked in parallel to produce a change list addressed by path: `$.customer.addresses[1].postalCode`, marked added, removed or modified. Types travel with the value, so a field that quietly became the string `"1"` where it used to be the number `1` surfaces as a type change, not a silent pass.
Beneath the change list sits a canonical text view — both documents re-serialized with sorted keys and normalized indentation, which is why the side-by-side stays quiet about formatting and loud about content. Parsing and comparison run inside a Web Worker, so a two-megabyte API capture never freezes the tab. A missing brace produces no error dialog: the page drops to a text comparison and names the pane that failed to parse. When the payload in front of you is really a flat table of records rather than a nested object, CSV Compare matches rows on a key column instead of by position.
Your payloads stay on your machine
The JSON that lands in a comparison box is seldom a toy example. It is a captured webhook body with a real customer email inside it, an authorization response still carrying a bearer token, a records export pulled straight out of production. None of that belongs in a POST to somebody else's server, and this page never asks for one: parsing, comparison and rendering are JavaScript executing in your own tab, with no upload endpoint behind them, no account, and nothing kept once you close it. Open your browser's network tab while you use this tool — you'll see no request carries your content. The verification steps are written out here.
Where a JSON diff earns its keep
- An integration engineer chasing a vendor change drops last month's captured webhook body beside this morning's. The path list points straight at `$.charge.metadata.order_ref`, renamed without a changelog entry, and at an amount field now arriving in minor units.
- A mobile developer debugging a decode failure compares the test fixture against the live staging response and finds `"quantity": "3"` where the client expects a number — the type badge catches what a text diff would render as an identical-looking line.
- A platform engineer auditing feature flags diffs two exported flag definitions before promoting a rollout, confirming that only the percentage targeting moved and no kill switch was flipped along the way. The exporter emits keys in hash order, which a character-level comparison would present as a total rewrite.
- A QA analyst with a red snapshot test pastes the expected and actual golden files. Fifty lines of reindented output collapse to the one array element the service started emitting out of order.
Frequently asked questions
Why does reordering keys show no change, but reordering an array does?
Because that is what the format means. RFC 8259 defines an object as unordered, so key sequence carries no information and is normalized away. Array elements are positional, so a move between index 0 and index 3 is reported. To ignore array order too, sort both sides before pasting.
How big a document can this handle?
Comparison stays live up to roughly 1 MB of combined input; above that you press Compare yourself so keystrokes stay responsive. Files run to about 10 MB per side comfortably, with a 50 MB hard ceiling. Deep nesting costs more than raw size — a recursive tree is the heavier job.
Does my JSON get uploaded for parsing?
No. There is no server-side parser in this product. `JSON.parse` and the comparator run in a Web Worker inside your browser, and the result lives only in that tab. DevTools shows an empty request log while you work; our privacy page lists what to look for.
What happens if one side is not valid JSON?
Nothing breaks. The semantic view steps aside, a notice tells you which pane failed and roughly where, and you get a character-accurate text diff instead. That fallback is often what you actually want when debugging a truncated response body or a stray trailing comma.
Can I compare NDJSON or JSON Lines?
Not as a single structured document — newline-delimited JSON is a stream of separate values, not one value, so the parser rejects it. Wrap both sides in square brackets with commas between records and the tree comparison works normally. Otherwise the text fallback still lines the records up.
Related tools
- YAML DiffSame structural engine, pointed at Kubernetes manifests and pipeline configs.
- XML DiffElement trees and attributes, with attribute ordering treated as noise.
- ENV File DiffKey-by-key comparison of dotenv files, missing variables called out.
- CSV CompareRow and cell comparison for flat exports, matched on a key column.
- Text ComparePlain two-pane text comparison when structure is beside the point.