Online Diff Tool
A free, in-browser diff tool that compares two payloads structurally — not just line by line. Paste two JSON, XML, SQL, or HTML documents, and the tool auto-detects the format, ignores cosmetic differences like key order or whitespace, and shows you what actually changed.
Open the Diff ToolWhat it does
Most diff tools treat their input as a list of lines and look for the shortest edit script that transforms one into the other. That is exactly the right algorithm for source code, but it is the wrong abstraction for structured data. Two JSON objects with the same keys in a different order are identical, but a line-based diff will flag every line as changed. Two XML documents with different whitespace are semantically equivalent, but a line-based diff will treat them as completely different.
This tool fixes that. For known structured formats it parses both inputs into a tree, normalizes the representations (sort keys, drop irrelevant whitespace, fold equivalent constructs), and compares the trees. For anything else — plain text, code, configuration — it falls back to a robust line-level diff. Either way, the result is a side-by-side view with synced scrolling and a structured diff log that explains every change in human language.
Who it's for
- Developers comparing API responses across versions, environments, or feature flags. "Why does staging return different data than production for the same request?" — this tool answers it in a few seconds.
- Schema reviewers looking at two versions of a JSON Schema, an OpenAPI spec, or a protobuf definition. Order-independent comparison surfaces real changes (a field added, a type widened) while ignoring file-level rearrangement.
- Ad-tech engineers diffing OpenRTB bid requests across SSPs, or two VAST tag chains, or two impression-tracking payloads, looking for the field that explains why one path works and the other does not.
- Code reviewers who already use git for source code diffs but want a quick side-by-side for non-source artifacts that live in tickets, emails, or chat.
- QA and support engineers attaching "actual vs expected" comparisons to bug reports without manually highlighting the differences.
When to use it
- Comparing JSON outputs from two API versions. Paste the old response into the left pane and the new response into the right. The diff log tells you which fields were added, removed, or changed in value.
- Checking schema migrations. Run the same query against the pre-migration and post-migration database, paste both result sets, and confirm only the columns you intended changed.
- Before-and-after diffs of configuration. Production config files, feature flags exported as JSON, Terraform plan output — any pair of states that you want to inspect for unintended drift.
- Bid-request and bid-response analysis. Diff a working bid against a non-working one and the difference jumps out: a missing
tagid, a differentcatlist, a flippedsecureflag. - Comparing two SQL queries that should be equivalent but are returning different result counts.
Features
| Feature | What it does |
|---|---|
| Auto-detect format | Sniffs the first non-whitespace character of both panes to decide if it is JSON, XML, SQL, or HTML. Falls back to text if either side is unrecognized. |
| Order-independent JSON keys | Object keys are compared by name, not by position. {"a":1,"b":2} and {"b":2,"a":1} are reported as identical. |
| Line-level diff for text | For non-structured input, a classic line-based diff with intra-line character highlighting. |
| Sync-scroll | Scrolling one pane scrolls the other to the aligned position. You never lose your place. |
| Structured diff log | A human-readable list of changes: "field user.email changed from X to Y", "array element items[3] added with id 42", "object key legacy_id removed". Exportable as JSON or plain text. |
| Whitespace-insensitive mode | For XML, HTML, and SQL: normalizes whitespace before comparing, so reformatting differences do not pollute the diff. |
| Ignore patterns | Optionally ignore specific JSON paths (e.g., $.timestamp, $.requestId) that always differ between runs and would otherwise add noise. |
How it differs from a text diff
The defining feature of this tool is that, for structured data, equality is semantic, not textual. Consider the following two JSON snippets.
// Left pane
{ "a": 1, "b": 2 }
// Right pane
{
"b": 2,
"a": 1
}
A line-based diff (the kind you get from diff, git diff, or most online tools) will report every line as changed. The opening brace moved, the values switched lines, the formatting is different. As a human reader, you know the two payloads carry exactly the same information.
This tool parses both sides, builds in-memory trees, and reports: "no changes." That is the same answer you would give if you read the JSON aloud. Equivalent reformatting is invisible; real differences — a value changed, a key added, an element inserted in an array — are loud.
Arrays are a deliberate edge case. By default arrays are compared positionally — order matters. If you want order-insensitive array comparison (think of a tags field that lists strings whose order is irrelevant), you can opt into it per-path in the ignore-patterns panel.
Why this matters in ad-tech. Bid requests routinely carry the same data in different shapes — one SSP puts cat as a list of strings, another puts it as an object keyed by IAB version, and a third puts the same content in ext. A textual diff hides the equivalence. A structural diff surfaces only the true difference.
The diff log
Alongside the side-by-side view, the tool produces a structured diff log: a flat list of every change, in JSON Path notation, with the old and new values inline. This is useful when you need to attach the diff to a ticket, a chat message, or a PR description — copying highlighted screenshots is awkward, but a text log of changes pastes cleanly anywhere.
{
"added": [
{ "path": "$.user.preferences.theme", "value": "dark" }
],
"removed": [
{ "path": "$.legacy_id", "value": 4271 }
],
"changed": [
{ "path": "$.updated_at", "from": "2026-06-29T10:00:00Z", "to": "2026-06-30T14:22:11Z" },
{ "path": "$.items[2].qty", "from": 1, "to": 3 }
]
}
Frequently asked questions
Does it handle huge files?
Tens of megabytes per pane work comfortably in modern browsers. For hundred-megabyte JSON dumps you will want a streaming tool instead — this tool keeps both trees in memory to compare them, and that has practical limits. For most API payloads, bid responses, schema files, and configuration snapshots, the limit will not be a concern.
Is it like git diff?
Conceptually similar — both compare two inputs and show what changed — but the algorithm is different. git diff is line-oriented because source code is naturally line-oriented. This tool is tree-oriented for structured formats and falls back to line-oriented for everything else. If you give it two source files (Python, Go, JS), the text mode produces output very similar to git diff.
Can I export the diff log?
Yes. The structured diff log can be copied to clipboard as JSON, plain text, or Markdown. The Markdown variant is convenient for pasting into pull-request comments or issue trackers that render Markdown.
Does it understand arrays where order matters versus where it doesn't?
By default, array order is significant. If you want to treat a specific array as a set (where reordering is irrelevant), add its JSON Path to the ignore-order patterns. For example, marking $.tags as unordered would make ["a","b"] and ["b","a"] compare as equal at that path.
What about XML element order?
For XML, sibling elements with the same tag name are compared positionally by default (because in XML, order is usually meaningful — think of the elements inside a VAST Creatives block). Attribute order, on the other hand, is never significant; attributes are normalized to alphabetical order before comparison.
Does it send my data anywhere?
No. Parsing, normalization, comparison, and rendering all happen client-side. Open DevTools and watch the network panel — no outbound requests beyond the static assets that load the page. That makes the tool safe for sensitive payloads that should not leave your machine.
Can I diff three or more documents?
Not directly. The tool compares two panes at a time. For three-way comparisons (which are usually about merge conflict resolution), use a dedicated three-way merge tool — they have different UX requirements and a separate algorithm.
How does it handle JSON numbers with precision differences?
Numbers are compared by their parsed value. 1.0, 1, and 1.0e0 are treated as equal. For very large integers that exceed JavaScript's safe-integer range, the tool falls back to string comparison so you do not get false equalities from silent precision loss.
Tip. Combined with the JSON beautifier in sort-keys mode, the diff tool becomes a "what really changed" inspector. Sort and beautify both inputs first, then diff — even purely textual diff tools downstream will then produce useful output.
Related tools
- JSON Beautifier and Validator — pre-format inputs before diffing
- ORTB Creative Renderer — render the bid response, then diff the markup
- Escape and unescape — when one side of the diff is a stringified version of the other