Compare JSON Online

Changes
Filter:
Examples:

Last updated: 2026-09-17

Paste two JSON documents to compare them side-by-side with aligned lines and highlighted changes. Jump between changes with next/prev, filter by type (added, removed, modified), and export a markdown report or JSON Patch. Semantic diff is on by default — key order does not matter. Everything runs locally in your browser.

What this tool does

Compares two JSON documents side-by-side with aligned lines and highlighted changes. Semantic diff is on by default, meaning key order does not matter. You can filter changes by type, jump between them with next and prev, ignore specific paths with glob patterns, and export a markdown report or JSON Patch (RFC 6902). All processing is local.

Example

Left (before):

{"order":{"id":42,"status":"pending","total":29.99,"items":[{"sku":"A1","qty":2}]}}

Right (after):

{"order":{"id":42,"status":"shipped","total":29.99,"items":[{"sku":"A1","qty":3}],"shippedAt":"2024-01-15"}}

Changes shown:

The side-by-side view aligns both documents by path and highlights each change in context.

Comparing API responses

When comparing two API responses from different requests, several fields may change on every call: timestamps, request IDs, pagination cursors, and rate-limit headers. Use the Ignore paths option to exclude these from the diff.

For example, to ignore updatedAt at any nesting level and requestId at the root:

*.updatedAt, $.requestId

Glob patterns supported: * matches any path segment, ? matches any single character. Multiple patterns are comma-separated.

Comparing configuration files

Configuration files often change in small ways between environments. Paste the development config on the left and the production config on the right to see exactly which keys differ. Key order is ignored by default, so reformatted configs do not produce noise.

For arrays of objects like server pools or feature flags, switch array matching to by key so reordered items do not show as changes. The tool auto-detects common key fields (id, _id, uuid, key, name) or you can specify one.

Filtering changes

The filter panel lets you show or hide changes by type:

FilterWhat it shows
AddedKeys or array elements present only in the right document
RemovedKeys or array elements present only in the left document
ModifiedKeys where the value changed between left and right
MovedArray elements that changed position (only in index mode)

Click any change to scroll both panels to that position.

Sharing comparisons

The Share button encodes both JSON inputs in the URL hash (the fragment after #). The data stays in the URL — it is never sent to a server. Anyone who opens the link sees the same comparison with the same inputs. This is useful for sharing a specific diff in a pull request, chat, or issue tracker without attaching files.

Do it in code

JavaScript (jsondiffpatch):

const { DiffPatcher } = require('jsondiffpatch');
const differ = new DiffPatcher({ objectHash: (item) => item.id });
const delta = differ.diff(leftObj, rightObj);
// Apply the delta to produce a side-by-side view
const { formatters } = require('jsondiffpatch');
const html = formatters.html.format(delta, leftObj);

Python (deepdiff):

from deepdiff import DeepDiff
diff = DeepDiff(left_dict, right_dict, ignore_order=True)
print(diff.to_json())

CLI (jd):

jd -t json file1.json file2.json
# Or with jq for a quick sorted comparison:
diff <(jq -S . file1.json) <(jq -S . file2.json)

Common mistakes when comparing

Understanding the change summary

The summary bar at the top of the comparison shows counts for each change type: added, removed, modified, and moved. These counts reflect the semantic diff, not line counts. A single modified value at a deep path counts as one change, not dozens of changed lines. The summary updates live as you toggle filters, so you always know how many changes of each type are visible.

Exporting comparison results

Three export formats are available:

Comparing database snapshots

Database export comparison is a common use case. Export two snapshots as JSON, paste them on each side, and the tool shows which rows were added, removed, or modified. If the export includes array indices that shift when rows are inserted or deleted, switch to by key matching using the primary key field so rows are matched by identity rather than position.

For large database exports with hundreds of rows, the comparison runs in a Web Worker to avoid freezing the page. The side-by-side view is virtualized, so only visible rows are rendered.

Comparing schema migrations

When a schema changes between versions, comparing the old and new schema JSON shows exactly which fields were added, renamed, or removed. Use the ignore paths feature to skip metadata fields like $schema or id that change between versions but are not semantically relevant to the migration.

Schema migration comparisons benefit from the change tree view, which groups changes by parent path. For a JSON Schema document, changes under properties show new or removed fields, while changes under required show which fields became mandatory or optional. The markdown export captures this in a format suitable for a migration changelog or release notes.

Comparing i18n translation files

Internationalization files are JSON objects where keys are translation identifiers and values are localized strings. Comparing two language files or two versions of the same language file shows which translations were added, which were removed, and which strings changed. Key order is ignored, so alphabetically sorted files and insertion-ordered files compare the same way.

For arrays of pluralization variants, switch to by key matching if the array elements have identifiers, or use index matching if positional order matters for the plural rules. When comparing a base locale against a target locale, added keys in the base file represent missing translations in the target, and removed keys represent obsolete translations that should be cleaned up.

Comparing feature flag configurations

Feature flag systems store their configuration as JSON objects where each flag has a name, enabled state, rollout percentage, and targeting rules. Comparing two versions of a flag configuration shows which flags were toggled, which targeting rules were adjusted, and which rollout percentages changed. Because flag configurations are typically nested objects with arrays of rule conditions, the by key matching mode helps when rules are reordered.

The markdown export is particularly useful here because it produces a changelog that can be attached to a deployment ticket or change request, documenting exactly which flags changed and how.

Comparing package manifests

Package manifests like package.json or pyproject.toml (when serialized to JSON) can be compared between branches to see which dependencies were added, updated, or removed. Version strings are compared as strings, not semantic versions, so a change from ^1.0.0 to ^1.1.0 shows as a modified value. Script entries, dependency lists, and configuration sections all diff cleanly because the comparison is semantic and key order does not matter.

When comparing lockfiles, which can be large and deeply nested, the Web Worker ensures the comparison does not block the page. The change tree view groups dependency changes under their parent path (dependencies, devDependencies, peerDependencies), making it easy to categorize additions and removals.

Comparing CI pipeline definitions

Continuous integration pipelines defined as JSON (GitHub Actions workflows stored in JSON form, GitLab CI configurations exported as JSON) can be compared between branches to review changes before merging. Job definitions, step sequences, environment variables, and matrix configurations all appear as nested objects and arrays. Steps that were reordered are detected as moved entries when using index matching, or as identical when using set matching.

Comparing API request payloads

When debugging API issues, comparing the request payload that works against the one that fails is a quick way to spot the difference. Paste both payloads and the side-by-side view highlights every field that differs. This is especially useful when the difference is subtle — a string versus a number, a missing optional field, or a nested object with an extra key.

Performance and large documents

The comparison engine handles large JSON documents efficiently. Inputs over 200KB are parsed and diffed in a Web Worker, which runs on a separate thread so the main thread stays responsive. The side-by-side view uses virtualized rendering — only the visible portion of each document is rendered in the DOM, so scrolling through a 50,000-line file does not lag.

The diff algorithm itself is based on jsondiffpatch, which uses a recursive object comparison with move detection. For most real-world JSON (configuration, API responses, database exports), the comparison completes in under a second. Pathological inputs with thousands of array elements that are all different can take longer, but the Web Worker ensures the page never freezes.

How the side-by-side view works

The side-by-side view renders both documents as formatted JSON with matching paths aligned on the same horizontal line. Added lines are highlighted on the right side, removed lines on the left, and modified lines on both sides with the old and new values shown. Clicking a change scrolls both panels to the aligned position. The next and prev buttons step through changes in path order, so you can review every difference without scrolling manually.

Edge cases handled

Frequently asked questions

What is the difference between JSON Diff and JSON Compare?
They use the same engine. JSON Diff defaults to a change tree view — best for reviewing what changed at a glance. JSON Compare defaults to a side-by-side view — best for seeing the changes in context. You can switch views in either tool.
How are API responses compared?
Paste the before response in editor A and the after response in editor B. The diff ignores key order by default. Use Ignore paths with patterns like *.updatedAt or *.requestId to skip fields that change on every request.
Can I compare JSON with different types for the same value?
Yes. Enable Loose type comparison to treat 1 and the string 1, or true and the string true, as equal. This is useful when comparing data from systems that serialize values differently, like query string parameters versus JSON bodies.
How does float tolerance work?
Set a tolerance value (e.g. 0.001) and floating-point numbers within that threshold are considered equal. This is useful for comparing computed values where tiny floating-point differences are expected from rounding or different calculation orders.
Can I share a comparison link?
Yes. The Share button encodes both JSON inputs in the URL hash. Anyone who opens the link sees the same comparison. The data is in the URL, not on a server — it is never uploaded.
Is my data sent to a server?
No. All parsing, diffing, and formatting happens in your browser. Your JSON never leaves your device. There is no backend, no API calls, and no analytics that process your input.
How do I compare two JSON files in the command line?
Use jq with diff: diff <(jq -S . file1.json) <(jq -S . file2.json). The -S flag sorts keys so order differences do not show. For structural diff, use jd (npm install -g jd) or the json-diff package in Python.
Can I compare arrays that are in different orders?
Yes. Switch the array matching mode to as unordered set. The comparator sorts both arrays by their serialized form before diffing, so elements that appear in different positions are treated as equal. For arrays of objects with an id field, use by key mode to match elements by their id.

Related tools