JSON Diff(JSON構造比較)
2つのJSONを構造レベルで比較し、追加・削除・変更をJSONPath単位で色分け表示します。キー順や整形の違いは無視されます。
How to Use the JSON Diff Tool
This free online JSON diff tool compares two JSON documents structurally. Paste the original JSON on the left, the new version on the right, and click Compare. Both documents are parsed and walked recursively, so indentation, line breaks, and key order never show up as noise — you only see real additions, removals, and value changes, each identified by its JSONPath (for example $.user.name or $.items[2]).
Features
- Structural comparison: formatting and whitespace differences are ignored by design
- Key-order independent by default, with an option to detect order changes too
- Results grouped as added (green), removed (red), and changed (yellow, old → new)
- JSONPath for every difference, ready to paste into a JSONPath query tool
- Summary counters so you can spot a large regression at a glance
- Runs entirely in your browser — no JSON ever leaves your device
What is a structural JSON diff?
A structural diff treats JSON as data, not text. The two inputs are parsed into objects and arrays, then compared node by node: keys present only in B are reported as added, keys present only in A as removed, and primitive values that differ as changed. Two documents that serialize differently but represent the same data — reordered keys, different indentation, minified versus pretty-printed — are reported as equal.
JSON Diff vs. text diff
A line-based text diff (like our Diff Checker) is the right tool for prose, code, or logs. For JSON it produces false positives whenever the serialization changes. Use this tool when you care about what the data says, and a text diff when you care about how the file is written.
JSON Diffの使い方
左の入力欄に変更前のJSON(A)、右に変更後のJSON(B)を貼り付けて「比較」を押すと、両者をパースして構造レベルで再帰比較します。 結果はJSONPath単位のテーブルで表示され、Bにだけ存在する項目は「追加」(緑)、Aにだけ存在する項目は「削除」(赤)、 値が変わった項目は「変更」(黄、旧値 → 新値)として色分けされます。インデント・改行・キーの並び順の違いは差分になりません。 「整形しただけのファイル」と「実際に値が変わったファイル」を確実に区別できるのが、行単位のテキストdiffとの最大の違いです。
実務での活用例
1. APIレスポンスの回帰確認
デプロイ前後で同じエンドポイントを叩き、レスポンスをAとBに貼って比較すると、「フィールドが消えていないか」 「値の型が変わっていないか」を数秒で確認できます。サーバー側のシリアライザが変わるとキー順が入れ替わることがよくありますが、 構造比較なら順序の変化はノイズにならず、$.data.price が 100 から "100"(文字列)に 変わったような、クライアントを壊す本質的な変化だけが浮かび上がります。
2. 設定ファイル・package.jsonの比較
環境ごとの設定JSON(staging / production)や、依存更新前後の package.json の比較にも向いています。 手で整形し直した設定ファイルは、テキストdiffだと全行が差分になりがちですが、本ツールなら 「実際に値が違うキーはどれか」だけを一覧できます。検出されたJSONPathはJSONPath Query Tester にそのまま貼って該当値を抽出できます。
3. Diff Checkerとの使い分け
コメント付きJSONC、行番号が重要なレビュー、JSON以外のテキストには行単位のDiff Checker を使ってください。本ツールは有効なJSONであることが前提で、 そのかわり「データとして何が変わったか」を正確に答えます。
制限事項: 配列はインデックス単位で比較
配列は先頭から同じインデックス同士を比較します。そのため先頭付近に1要素を挿入すると、後続の要素がすべてずれて 「変更」として報告されます。LCS(最長共通部分列)による要素の移動・挿入検出は将来対応の予定です。 現状では、IDなど一意なキーで配列をソートしてから比較する(例: jq 'sort_by(.id)')と実用的な結果になります。
よくあるエラーと対処 / Common Errors and Fixes
比較時に遭遇しやすいエラーと「期待と違う結果」の原因をまとめました。パースエラーのメッセージは V8 (Chrome/Node.js) 基準です。
Frequent errors and unexpected results when comparing JSON, with fixes. Parse error messages follow V8 (Chrome/Node.js).
| エラー / Error | 原因 / Cause | 対処 / Fix |
|---|---|---|
JSON A: Unexpected token ... | 左側の入力が不正なJSON(末尾カンマ・シングルクォートなど) Left input is invalid JSON (trailing comma, single quotes, etc.) | JSON Formatterで構文エラー箇所を特定して修正 Locate and fix the syntax error with the JSON Formatter |
JSON B: Unexpected end of JSON input | コピー時に末尾が欠落し閉じ括弧が不足 Truncated copy; missing closing bracket | 元データを再コピーし、末尾の } / ] を確認Re-copy the source and verify trailing }/] |
| 見た目は違うのに差分0件 Inputs look different but no diff reported | キー順・インデント・空白だけの違いは構造比較では等価 Key order, indentation and whitespace are ignored by structural comparison | 仕様どおり。テキストレベルの違いを見たい場合はDiff Checkerへ Working as intended; use the text Diff Checker for textual differences |
| 配列に1要素挿入しただけで大量の「変更」 One array insertion reports many changes | インデックス単位比較のため後続要素がすべてずれる Index-based comparison shifts every later element | 一意キーでソートしてから比較(jq 'sort_by(.id)')。LCSによる移動検出は将来対応Sort by a stable key first; LCS move detection is planned |
1 と "1" が「変更」扱い1 vs "1" reported as changed | number と string は型が異なる Number and string are different types | 仕様どおり。型変化はAPI回帰の重要シグナルなので意図的に検出 Intentional: type changes are a key API-regression signal |
null とキー欠落が別扱いnull vs missing key treated differently | 値が null のキーは存在し、欠落キーは存在しないA key with null exists; a missing key does not | JSONの意味論どおり。null→欠落は「削除」、値→null は「変更」Per JSON semantics: null→missing is removed; value→null is changed |
日本語キーが $['キー'] 表示Non-ASCII keys shown as $['key'] | ドット記法は英数字とアンダースコアの識別子のみ対応 Dot notation only supports identifier-style keys | JSONPath仕様どおりのブラケット記法。そのままJSONPathツールで利用可能 Standard bracket notation; usable as-is in JSONPath tools |
| 巨大JSONでブラウザが重い Browser slows down on huge JSON | 数十MB級の入力はパース・描画コストが高い Tens of MB cost a lot to parse and render | 比較したいサブツリーだけを抽出して貼り付ける(jq .data など)Extract only the subtree you need (e.g. jq .data) |
言語別コード例 / Code Examples by Language
このツールと同等の「構造レベルのJSON比較」をコードで再現する最小サンプルです。
Minimal snippets that reproduce a structural JSON comparison in code.
JavaScript / TypeScript
// 構造比較 / Structural deep-diff (simplified)
function diff(a, b, path = "$", out = []) {
const bothObj = a !== null && b !== null &&
typeof a === "object" && typeof b === "object" &&
Array.isArray(a) === Array.isArray(b);
if (bothObj) {
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
for (const k of keys) {
const p = Array.isArray(a) ? path + "[" + k + "]" : path + "." + k;
if (!(k in a)) out.push({ path: p, kind: "added" });
else if (!(k in b)) out.push({ path: p, kind: "removed" });
else diff(a[k], b[k], p, out);
}
} else if (a !== b) {
out.push({ path, kind: "changed", old: a, new: b });
}
return out;
}Python
def diff(a, b, path="$", out=None):
out = [] if out is None else out
if isinstance(a, dict) and isinstance(b, dict):
for k in a.keys() | b.keys():
p = f"{path}.{k}"
if k not in a: out.append(("added", p))
elif k not in b: out.append(("removed", p))
else: diff(a[k], b[k], p, out)
elif isinstance(a, list) and isinstance(b, list):
for i in range(max(len(a), len(b))):
p = f"{path}[{i}]"
if i >= len(a): out.append(("added", p))
elif i >= len(b): out.append(("removed", p))
else: diff(a[i], b[i], p, out)
elif a != b:
out.append(("changed", path, a, b))
return outGo
// encoding/json で any にデコードし、構造的に等価か判定
var a, b any
_ = json.Unmarshal(rawA, &a)
_ = json.Unmarshal(rawB, &b)
if !reflect.DeepEqual(a, b) {
// 差分あり。map[string]any / []any を再帰的に
// たどれば、どのパスが違うかを特定できる
}Shell (jq + diff)
# jq -S でキーをソートして正規化してからテキスト diff
diff <(jq -S . a.json) <(jq -S . b.json)
# 正規化を1行に圧縮して比較(等価なら出力なし)
diff <(jq -cS . a.json) <(jq -cS . b.json)Before / After 実例 / Before & After
例1: APIレスポンスの回帰確認 / Catch an API regression
JSON A(旧)と JSON B(新):
A: {"user":{"id":42,"plan":"free","roles":["viewer"]},"meta":{"version":"1.0.0"}}
B: {"meta":{"version":"1.1.0","updatedAt":"2026-06-01"},
"user":{"id":42,"plan":"pro","roles":["viewer","editor"]}}↓ 比較結果(トップレベルのキー順の入れ替えは差分にならない)
changed $.user.plan "free" -> "pro"
added $.user.roles[1] "editor"
changed $.meta.version "1.0.0" -> "1.1.0"
added $.meta.updatedAt "2026-06-01"例2: キー順と整形だけが違う場合 / Only key order and formatting differ
A: {"b": 2, "a": 1}
B: {
"a": 1,
"b": 2
}↓
差分はありません(構造的に等価) / No differences — structurally equal例3: 配列への挿入(制限事項のデモ) / Array insertion (known limitation)
A: [10, 20, 30]
B: [5, 10, 20, 30]↓ インデックス単位比較のため、要素のずれがすべて「変更」になる
changed $[0] 10 -> 5
changed $[1] 20 -> 10
changed $[2] 30 -> 20
added $[3] 30一意キーを持つ配列なら、事前に jq 'sort_by(.id)' などでソートすると安定した比較ができます。
For arrays of objects, sort by a stable key first (e.g. jq 'sort_by(.id)') to get stable results.
Why browser-only? / なぜブラウザ完結か
The JSON you compare with this tool is often the most sensitive data you handle: raw API responses with access tokens and user records, or production configuration files with database credentials. Sending two full copies of that data to a server-hosted diff service doubles the exposure — both versions leave your machine, may be logged, and may be retained. This tool performs JSON.parse and the recursive comparison entirely inside your browser with plain JavaScript. No network request is made when you click Compare, nothing is stored, and the page works even offline once loaded. You can verify this yourself: open DevTools, switch to the Network tab, run a comparison, and watch the tab stay empty.
比較対象のJSONには、アクセストークンを含むAPIレスポンスやDB認証情報入りの設定ファイルなど、 機密性の高いデータが含まれがちです。サーバー型のdiffサービスでは新旧2つの完全なコピーが外部へ送信されますが、 本ツールはパースも再帰比較もすべてブラウザ内のJavaScriptで完結します。「比較」を押しても通信は一切発生せず、 DevTools → Network タブが空のままであることをいつでも確認できます。
関連ツール / Related Tools
開発をもっと効率的に
PR