Skip to content

JSON Diff Checker

Compare two JSON documents and see exactly which keys were added, removed, or changed, with the full path to each — free and instant.

JSON Diff Checker
Compare
Private — your inputs stay in your browser
Up to 200 KB; stays in your browser
Up to 200 KB; stays in your browser
Advanced options

Exact paths separated by commas, e.g. /meta/updatedAt, /requestId. Escape / in a key as ~1 and ~ as ~0.

Your result

Result
Different

1 added, 0 removed, 1 changed.

Keys added
1
Keys removed
0
More result details
Values changed1
Differences by path
PathStatusBeforeAfter
versionchanged12
tools[2]added—"case-converter"

Diff (normalized comparison)

First JSON
Second JSON
{
{
"name": "UToolios",
"name": "UToolios",
"tools": [
"tools": [
"mortgage-calculator",
"mortgage-calculator",
"bmi-calculator"
"bmi-calculator",
"case-converter"
],
],
"version": 1
"version": 2
}
}
Method, assumptions, and tips
Why this matters

Ignored fields use exact JSON Pointers. Array-by-ID mode sorts unique IDs before comparison; displayed array indices refer to that normalized order.

Comparison is by structure and value, not by text — reformatting, re-indenting, or reordering object keys never counts as a difference.

The colored line-by-line view below is generated by re-printing both documents with sorted keys and consistent indentation first, then diffing that — so it inherits the same "formatting never matters" guarantee as the summary above it.

Arrays compare by position by default. Optional ID mode sorts record arrays first; displayed indices then refer to normalized order.

A key present in only one document shows as added or removed; a key present in both with a different value (or a different type entirely) shows as changed.

Numbers are compared by value, so 1 and 1.0 are treated as identical.

About this tool

The comparison runs entirely in your browser as you type — neither document is ever uploaded to a server.

Tip

Key order never counts as a difference — {"a":1,"b":2} and {"b":2,"a":1} are treated as identical, since JSON objects have no defined order.

Best for

Checking what an API response actually changed between two calls, or verifying a config file edit only touched the keys you intended.

Maintained by Sujit MaharjanLast updated 17 October 2026How this content is made

How it works

1
Paste the first JSON
The "before" version — an old API response, a previous config, or anything you are comparing from.
2
Paste the second JSON
The "after" version. The comparison runs the instant both documents parse successfully.
3
Read the summary
Added, removed, and changed key counts appear immediately, followed by "Identical" if nothing differs at all.
4
Check the differences table
Every difference lists its full path (e.g. user.roles[2]), so nested changes are exactly as easy to find as top-level ones.

Compare an API response without chasing noise

A useful API comparison separates a business change from a new request ID, a different timestamp or a reordered list. JSON Diff Checker parses both documents, compares their values and shows added, removed and changed paths. Whitespace and object-key order do not affect the result. Array order does, unless you choose array-by-ID matching.

The examples below use invented records, not customer data. The “API change: ignore request ID” and “Reordered records: match by ID” buttons above load these scenarios into the working tool.

Example 1: a price changed, and so did the request ID

First response:

{
  "requestId": "demo-before",
  "product": {"id": "sku-7", "price": 19.5, "stock": 8}
}

Second response:

{
  "requestId": "demo-after",
  "product": {"id": "sku-7", "price": 21, "stock": 8}
}

With default options, expect two changed values: requestId and product.price. There are no added or removed keys. In Advanced options, enter /requestId under Ignore JSON Pointers. The expected result becomes one changed value, product.price, from 19.5 to 21.

Ignore a field only after deciding it is irrelevant to your investigation. Ignoring a price, permission or status field can hide the very regression you are looking for. “Identical” with ignored paths means the remaining compared data matches; it does not mean the source files are identical.

Example 2: reordered records with one real edit

First response:

[{"id":"a","stock":8},{"id":"b","stock":3}]

Second response:

[{"id":"b","stock":4},{"id":"a","stock":8}]

By position, expect four changed values: each index now has a different ID and a different stock value. If order has no meaning for this endpoint, choose “By unique ID field” and use id. The tool sorts both arrays by the serialized ID and reports one changed value, [1].stock, from 3 to 4. That index belongs to the normalized order, where record b follows record a; it is not the original second response’s index.

ID mode applies to every array in the document, including nested arrays. Every array item must be an object with a unique string, number or boolean ID. A missing ID, duplicate ID or array of strings produces an error. Numeric 1 and string "1" are different IDs. Use positional mode if the document mixes record arrays and primitive arrays, or compare just the relevant record array.

Read the path and the status together

StatusMeaningExample
AddedOnly the second document has this key or array positionproduct.discount appears
RemovedOnly the first document has itproduct.legacyCode disappears
ChangedBoth have the position, but the values or types differproduct.price changes from 19.5 to 21

A newly added object is one added entry containing that object, rather than a count of every leaf it contains. Counts describe reported entries, not changed lines. The visual diff prints normalized JSON before comparing lines, so one changed value can occupy a removed line and an added line.

Paths use dots for keys and brackets for zero-based array indices. users[0].roles[1] means the second role of the first user. (root) means the whole top-level value changed. Keys that themselves contain dots or brackets can make these display paths ambiguous: check the surrounding JSON in that case. Display paths are not the JSON Pointers used by Ignore JSON Pointers.

Ignore a nested field precisely

An ignored pointer begins with / and names an exact location. /meta/updatedAt ignores updatedAt inside meta; it does not ignore every key with that name. /items/0/checkedAt applies to the original first item before ID sorting. There are no wildcard pointers. A comma separates pointers, so this control cannot express a key containing a literal comma.

For a key containing /, write ~1; for a key containing ~, write ~0. The pointer /a~1b/~0tag addresses ~tag inside a/b. Ignoring an array index replaces that position with null during normalization rather than shifting later items. In ID mode this can fail the requirement that every array item have an ID.

Know what the parser can hide

This tool uses JavaScript numbers. 9007199254740992 and 9007199254740993 can parse to the same value, so “Identical” is not proof of exact integer equality beyond the safe-integer range. Keep long record IDs as strings. Duplicate object keys keep only their last value. Spellings such as 1, 1.0 and 1e0 compare equal.

Each input is limited to 200,000 characters; normalized documents are limited to 2,000 formatted lines, and nesting deeper than 100 levels is rejected. A compact single-line document can exceed the formatted-line limit after expansion. Compare a smaller section when a limit is reached.

Use JSON Formatter to resolve syntax errors first. Use Text Diff Checker when the original spelling, whitespace or ordering is what you need to review. Neither comparison establishes that an API satisfies your business schema.

References and reproducibility

RFC 8259 defines JSON objects, arrays and interoperability limits. RFC 6901 defines pointer escaping. ID matching, ignored-field behavior and display paths above describe this tool’s implementation. Both documents are processed locally; sharing this page shares its URL, not your inputs.

FAQ

Can I ignore fields or match arrays by ID?

Advanced options accept comma-separated JSON Pointers such as /meta/updatedAt; escape ~ as ~0 and / as ~1. Array-by-ID mode requires a unique primitive ID on every object in each array. Paths describe normalized order. Comparison is limited to 2,000 formatted lines per document.

Does key order matter?

No. {"a": 1, "b": 2} and {"b": 2, "a": 1} are reported as identical — JSON objects have no defined key order, so this tool compares the actual keys and values, not the order they happen to appear in the text.

Does formatting or indentation count as a difference?

No. Both documents are parsed before comparison, so extra whitespace, different indentation, or minified versus pretty-printed JSON never shows up as a difference — only the underlying data is compared.

How do I read a path like "user.roles[2]"?

Dots step into object keys and brackets step into array indexes, left to right from the document root. "user.roles[2]" means the third item (index 2, since indexing starts at 0) of the "roles" array, inside the "user" object.

What does "(root)" mean in the path column?

It means the difference is at the very top level of the document — for example, one document is a JSON array and the other is a JSON object, so there is no meaningful key path to point to.

How are arrays compared?

By position by default. In Advanced options, ID mode matches record arrays by a unique ID field and ignores their order. It applies to every array, so each item must be an object with a unique string, number or boolean ID. Displayed indices refer to the sorted comparison.

Are 1 and 1.0 treated as the same number?

Yes. Numbers are compared by their parsed value, not their original text representation, so 1, 1.0, and 1e0 are all treated as identical if they appear in the two documents.

What happens if one of my documents has invalid JSON?

The tool tells you which document (first or second) failed to parse, and the line and column where the problem starts, the same way the JSON Formatter tool does. Fix the syntax error and the comparison runs automatically.

Can it compare deeply nested documents?

Nesting deeper than 100 levels is rejected. Each input is limited to 200,000 characters and each normalized document to 2,000 formatted lines. Compare a smaller section if a limit is reached.

Is my JSON uploaded anywhere?

No. Both documents are parsed and compared entirely in your browser. Nothing is uploaded, logged, or stored, so comparing a real API response, config file, or private data structure is safe from this page's side.

Why does changing an object to a string at the same key show as "changed" rather than "removed" and "added"?

Because the key itself still exists in both documents — only the value at that key changed (from one type to a completely different one). The tool shows this as a single "changed" entry with both the old and new value, rather than treating it as the key disappearing and a new one appearing.

Related tools

UTooliosUToolios
Theme