元の JSON
変更後の JSON

JSON Diff: 2つのJSONファイルをオンラインで比較

2つのJSONを貼り付け、整形して、左右に並べて比較。バリデーション、整形表示、ミニファイ機能を内蔵。

JSON比較ツールとは?

ブラウザ内で動く無料の2つのJSONドキュメント比較ツールです。左に古いバージョン、右に新しいバージョンを貼り付けると、文字単位で差分が点灯します。データはマシンの外には出ません。

検証にはブラウザのネイティブなJSON.parseを使用しています。JSONが1行のミニファイされた巨大な塊になっているときのためのFormatボタン、その逆のためのMinifyボタン、そして入力中に構文エラーを示すライブバリデーションを備えています。

GitHubのPRで6,000行のopenapi.jsonのdiffを見つめながら、ダウンストリームのクライアントを壊した1つのフィールドを探した経験があるなら、これは数秒でそこにたどり着けるツールです。

diffの実際の仕組み

差分は文字単位で、その後セマンティックな後処理でクリーンアップされ、ハイライトがランダムな文字ではなく意味のある塊に当たるようになっています。挿入は右ペインで緑、削除は左ペインで赤に表示されます。

JSONには仕様で明示されている独自の癖があります。RFC 8259のJSON仕様では、オブジェクトは順序を持たないと定義されているため、キーの並べ替えは技術的には何もしないのと同じですが、テキストdiffはそれを差分として扱います。これに対しては、各サイドにFormatボタンを用意することで対応しています。両方を整形してから比較すれば、順序が一貫します。より深い構造的な作業には、JSON Patch (RFC 6902)やよりシンプルなJSON Merge Patch形式 (RFC 7396)を見てください。これらはJSONの変更をデータとして記述する2つの標準的な方法です。

ハッシュ化や署名のために順序が重要になる場合は、関連する仕様はRFC 8785(JSON Canonicalization Scheme)です。キーをソートし、数値の表記を正規化してから差分を取ります。

3ステップでJSONを比較する方法

テキストペインが2つ、diffが1つ。登録もアップロードもサーバーへの往復もありません。

  1. 1

    JSONを貼り付けるかアップロード

    古いJSONを左に、新しいJSONを右に貼り付けます。あるいは、どちらかのサイドでUploadをクリックして.jsonファイルを直接読み込みます。Sampleボタンを押すと、ツールの動きをまず見たい場合に備えて、両方のペインに小さな例が入ります。

  2. 2

    公平な比較のために両側を整形

    各ペインでFormatをクリックすると、2スペースのインデントで整形表示されます。これにより空白や改行が正規化され、diffがフォーマットの違いではなく実際のデータ変更をハイライトするようになります。JSONがエラーなくパースされると、検証バッジが緑になります。

  3. 3

    diffを読む

    削除は左に赤いハイライトで、挿入は右に緑のハイライトで表示されます。どちらか一方をスクロールすると、もう一方も追従します。各ヘッダーの変更カウントが、diffで見つかった編集の件数を示します。

JSON diffが適しているとき

適用前にIAMポリシーの変更を監査する

現在のaws iam get-policy-versionの出力と、提案されているJSONを貼り付けて比較すれば、どのActionエントリが追加されたか、あるいは以前は具体的だったステートメントに誰かが"Resource": "*"を忍び込ませていないかが正確に分かります。AWSコンソールは保存時にステートメントを並べ替えるため、GitHubのdiffは誤解を招きます。ここで両側を整形すれば、本当の変更がはっきりします。

Terraformプランの静かなドリフトを発見する

terraform show -json tfplanが4 MBの塊を返したとき、目視は絶望的です。今日のプランを昨日のプランと比較して、リファクタPRの下に誰かが追加したaws_security_group_ruleや、こっそり消えたlifecycle.ignore_changesブロックを浮かび上がらせましょう。

マージ前にOpenAPIスキーマの変更をレビューする

コードジェネレータがpathsをアルファベット順に並べ替えると、6,000行のopenapi.jsonのdiffは読めません。両側を整形して比較すれば、本当の変更が浮かび上がります。CreateOrderRequestに追加されたrequiredフィールドや、スキーマがこっそりstringからstring | nullに変わった200レスポンスなど。

マージ後にpackage-lock.jsonをデバッグする

package-lock.jsonのコンフリクトを解決した後、解決したファイルをmainのロックファイルと比較して、推移的なダウングレードを捕まえましょう。npmは同じsemver範囲をマシンによって異なる正確なバージョンに解決することがあり、これが「自分のマシンでは動くがCIで落ちる」の本当の原因です。各フィールドの意味については、package-lock.jsonのドキュメントを読んでください。

環境間でElasticsearchのマッピングを比較する

staging本番からGET /my-index/_mappingを取得して、両方をdiffに入れます。本番はまだ、stagingが先のスプリントで"keyword"に移行したフィールドに対して"type": "text"を持っているかもしれません。これが、集計クエリが本番では何も返さずローカルでは動く理由です。マッピングは5、6階層ネストし、テキストdiffだとこれがノイズに埋もれます。

不安定なAPIモックを再現する

PlaywrightのテストがローカルでパスしてCIで落ちるとき、テストが実際に見たJSONレスポンスボディをキャプチャして、リポジトリのfixtureと比較しましょう。多くの場合、誰も固定しなかったcreatedAtのタイムスタンプやtraceIdフィールドが原因で、構造的diffは整形済みテキストの壁に放り込まれる代わりに、問題のキーを一目で分かるようにしてくれます。

JSONクイックリファレンス

このツールが最もよく表に出すパースのエッジケースを短くまとめたチートシートです。すべてJSON仕様に基づいています。

TopicWhat this tool does
オブジェクトのキー順仕様上は順序なし。{"a":1,"b":2}{"b":2,"a":1}と等しい。比較前の正規化にはSort keysを使います。
配列の順序順序あり。[1,2,3][3,2,1]と等しくありません。用途で順序が重要でない場合は手動でソートしてください。
末尾カンマ不可。{ "a": 1, }は標準JSONではパースエラーです。スーパーセットであるJSON5/JSONCでは可。先に取り除いてください。
コメント不可。// このようにはパースエラーです。JSON5とJSONCは受け付けますが、このツールはRFC 8259の厳密な文法に従います。
数値64ビットIEEE 754浮動小数点としてパースされます。0.1 + 0.2 = 0.30000000000000004。2^53 − 1を超える整数は精度が失われます。スノーフレークIDは文字列として保存してください。
重複キー仕様では未定義動作とされています。多くのパーサーは最後の出現を残します。diffはすべて表示しますが、これは設定ファイルを監査するときに通常欲しい挙動です。
エンコーディングUTF-8のみ。RFC 8259はドキュメントの先頭にUTF-8 BOMを置くことを禁止しています。受け入れるパーサーもありますが、仕様上は不可です。
Nullと欠如の違い値がnullのキーは存在しています。欠如しているキーは存在しません。JavaScriptのundefinedとは異なり、undefinedにはJSON表現がありません。

JSON diff: よくある質問

貼り付けたJSONはどこかに保存されたりアップロードされたりしますか?

いいえ。diffは完全にブラウザ内で動作します。サーバーへの送信、ログ、保存は一切ありません。社内APIのレスポンスやIAMポリシーを貼り付けてタブを閉じれば、コピーはどこにも残りません。確認するには、DevToolsを開いてNetworkタブに切り替え、見ていてください。比較しても外部への通信はありません。

キーの並べ替えやJSONのpretty-printは変更として表示されますか?

はい、両方とも表示されます。テキストdiffは行ごとに文字を比較するため、再フォーマット、キーの並べ替え、空白の変更が、データが同じでも差分として現れます。まず両方のペインでFormatボタンをクリックすれば、diffは実際のデータ変更に集中します。キーの順序を完全に無視した構造的な比較が欲しい場合は、比較前に両側のキーをソートしてください。

JSONオブジェクトのキーの順序は重要ですか?

オブジェクトのキーについては重要ではありません。JSONの仕様ではオブジェクトは順序を持たないとされているため、{"a":1,"b":2}{"b":2,"a":1}は同じデータを表します。文字単位のdiffは並べ替えを差分として扱うので、Formatボタンが意味を持ちます。配列は別で、[1,2,3][3,2,1]は等しくありません。JSONでは配列の順序は意味を持つからです。

なぜ私のdiffで0.1 + 0.2が0.3にならないのですか?

IEEE 754浮動小数点のためです。0.1 + 0.2は実際には0.30000000000000004であり、JSON.parseは数値を64ビット浮動小数点として読みます。大きな整数も同じ限界に当たります。2^53 - 1(9007199254740991)を超えると精度が失われるので、Twitterのスノーフレーク形式のIDはラウンドトリップしません。精度が重要なら、文字列として保存してください。

コメントや末尾カンマ付きのJSONを貼り付けられますか?

標準のJSONはどちらも許可しません。{ "a": 1, }// コメントはパースエラーになります。それはJSON5またはJSONC(VS Codeがsettings.jsonに使う形式)で、こちらはスーパーセットです。先にコメントと末尾カンマを取り除いてください。私たちは意図してRFC 8259の厳密な文法に従っており、diffがあなたのAPIが実際に受け付けるものに一致するようにしています。

どのくらいの大きさのJSONまでなら遅くならずに比較できますか?

数MBまでなら問題なく、1秒未満です。10MBを超えるとブラウザに負担を感じ始めますが、これは主にdiffの計算ではなく描画にコストがかかるためです。50MB以上のエクスポートでは、まずjqで両側を関心のあるサブツリーに絞ってから貼り付けてください。

プライバシーと仕組み

あなたのJSONはブラウザの外には出ません。パーサー、フォーマッター、diffはすべてあなたのマシン上でローカルに動きます。入力に対する分析もログも、「親切な」クラウドへの往復もありません。パースにはブラウザネイティブのJSON.parseを使用し、私たちが従うJSON仕様はRFC 8259です。