ShotMark
Skip to Content

JSON Compare

Deep-compare two JSON objects and highlight added, removed, and changed keys.

Original JSON
Modified JSON
Differences
Waiting for input

What is JSON Compare?

A JSON compare tool deep-compares two JSON objects key by key and reports every difference between them, including keys that were added, removed, or changed in value. Unlike a plain text diff, it walks the structure recursively, ignores cosmetic whitespace differences, and reports each change against its full path inside the document.

This JSON compare runs entirely in your browser. Paste an original on the left and a modified version on the right, and the tool parses both documents, traverses every nested key, and renders color-coded rows for additions (green), removals (red), and changes (amber). QA engineers, backend developers, and API consumers reach for it when a text diff is too noisy and only the actual structural delta matters.

Why use this JSON compare?

  • Skip whitespace and key-order noise. The compare parses both inputs into native objects first, so reordered keys or different indentation do not show up as fake changes.
  • See full paths for every difference. Each change row prints the JSON path (user.address.zip), which is faster to navigate than scrolling two side-by-side text blobs.
  • Distinguish three change kinds. Added, removed, and changed rows are color-coded and labeled separately, so you can read the delta at a glance without parsing diff markers.
  • Stay private by default. All parsing and comparison happens client-side. The payloads never reach a server, so production webhooks, OAuth tokens, and PII stay on your machine.
  • Catch silent contract changes. Comparing a serializer’s output before and after a refactor surfaces accidentally renamed keys or stripped fields that unit tests miss.

How to use the JSON compare

  1. Paste the original payload into the Original JSON textarea on the left.
  2. Paste the modified payload into the Modified JSON textarea on the right.
  3. Read the Differences panel below. Green rows are additions, red rows are removals, amber rows are value changes.
  4. If either input is invalid, the parser error appears above the diff. Fix the syntax and the diff refreshes.

A simple comparison looks like this:

// Original { "name": "Ada", "role": "admin", "active": true } // Modified { "name": "Ada", "role": "owner", "team": "core" } // Diff ~ role "admin""owner" - active true + team "core"

How the deep compare works

The compare walks both trees in parallel starting at the root. At each level it collects the union of keys, then for every key it picks one of four outcomes.

ConditionOutcomeLabel
Key only in originalRemoved-
Key only in modifiedAdded+
Both sides, equal primitivesUnchanged (hidden by default)
Both sides, different primitivesChanged~
Both sides, both objectsRecurse(continues)
Both sides, both arraysCompare positionally(per index)

Arrays are compared by index, so inserting an element at the start shifts every later element and marks each as changed. If your arrays are set-like, sort both sides by a stable key before comparing. The compare also treats null and undefined-shaped values as distinct types, matching how strict JSON serializers behave.

Common use cases

  • QA engineers validating fix regressions. Compare the API response before and after a hotfix to confirm only the targeted field changed.
  • Backend developers reviewing serializer output. Diff the JSON your service emits to catch silently renamed or dropped keys after a model refactor.
  • DevOps engineers auditing config drift. Compare two package.json, Helm values, or environment exports to see exactly which settings moved between releases.
  • API consumers debugging integration breaks. Drop the payload from a partner’s sandbox vs production to find the field the partner changed without telling you.
  • Tech writers updating API docs. Compare yesterday’s example payload with today’s to find the breaking field name change you need to document.

JSON compare vs alternatives

ToolBest forOfflineCostLimitations
diff (CLI)Line-level text diffsYesFreeTreats whitespace and reordering as changes.
jd or json-diff (CLI)Scripted JSON diffsYesFreeRequires installation; no UI.
Beyond CompareVisual file diffs across formatsYes$60Paid; heavier than a browser tool.
This JSON compareQuick paste, structural diff in browserYes (in browser)FreeArrays compared positionally only.

Frequently asked questions

What is the difference between a JSON compare and a text diff?

A text diff compares characters line by line, so reordered keys, different indentation, or a trailing newline all appear as changes. A JSON compare parses both inputs into objects first and only reports structural differences. This means a key renamed from userId to user_id shows as one change, not several line edits.

Why does my compare show every array element as changed?

Arrays are compared by index. Inserting one element at position zero shifts every other element down by one, and each shifted element is reported as changed at that index. If your array is order-independent, sort both arrays by a stable key (like id) before pasting.

Can I ignore specific keys during the compare?

Not in this tool. The compare reports every difference. If a key is noisy (updatedAt, requestId), strip it from both inputs before pasting, or run both payloads through jq 'del(.updatedAt)' first.

How does the compare handle nested objects?

It recurses into every nested object and reports differences at the deepest level. A change to user.address.zip shows as a single row at that exact path, not as a change at user. This makes the diff precise and easy to act on.

Is null treated the same as a missing key?

No. A key with the value null exists in the object. A missing key does not exist. The compare reports {"a": null} vs {} as a removal, because removing the key changes the object’s shape even when the value was already null. This matches how most strict JSON consumers behave.

What happens if one side is invalid JSON?

The parser error appears above the diff panel and the comparison is skipped. Fix the syntax, usually a trailing comma, an unquoted key, or a single-quoted string, and the diff refreshes the moment both sides parse cleanly.

How big a payload can I compare?

A few megabytes per side is comfortable. The browser parses both documents into memory and renders one row per difference, so multi-megabyte payloads with thousands of changes can slow the tab. For large diffs, pre-filter both inputs to the subtree you care about.

Can I use this to compare two JSON Schema documents?

Yes, since JSON Schema is itself JSON. The compare will surface every keyword change (required, properties.x.type, etc). It does not understand schema semantics, so a logically equivalent schema written differently will still show structural differences.

Like this tool?

ShotMark captures what you do here, in one click.

The traces, payloads, and tests you run by hand? ShotMark grabs the whole bug and hands it to your AI agent.

Private beta accessFounding pricing lockNo spam ever