format / diff
JSON差分ツール
2つのJSONオブジェクトをキー・パス単位で比較し、追加・削除・変更箇所を色分けして表示します。 ネストしたオブジェクトや配列にも対応。入力データはサーバーに送信されません。
左右のテキストエリアにJSONを入力し、「差分を計算」ボタンを押してください
使い方
01- 左側(before)に変更前のJSONを入力します
- 右側(after)に変更後のJSONを入力します
- 「差分を計算」ボタンを押すと、キー・パス単位の差分が一覧表示されます
- 緑色(
+)が追加、赤色(-)が削除、黄色(~)が値の変更です - パス列はドット記法(例:
user.address.city)や配列インデックス(例:items[2])で表示されます
実装コード
02コアロジックは再帰的な深さ優先探索でJSONを走査しています。 オブジェクト・配列・プリミティブ値を型判別しながら差分エントリを生成します。 外部ライブラリは不要なので、そのままコピーしてご利用いただけます。
export type Result<T> = { ok: true; output: T } | { ok: false; error: string }
export type DiffEntry = {
path: string
type: 'added' | 'removed' | 'changed' | 'unchanged'
left?: unknown
right?: unknown
}
function diffValues(left: unknown, right: unknown, path: string, result: DiffEntry[]): void {
if (left === right) {
result.push({ path, type: 'unchanged', left, right })
return
}
if (
typeof left === 'object' && left !== null &&
typeof right === 'object' && right !== null &&
!Array.isArray(left) && !Array.isArray(right)
) {
const leftObj = left as Record<string, unknown>
const rightObj = right as Record<string, unknown>
const keys = new Set([...Object.keys(leftObj), ...Object.keys(rightObj)])
for (const key of keys) {
const childPath = path ? `${path}.${key}` : key
if (!(key in leftObj)) {
result.push({ path: childPath, type: 'added', right: rightObj[key] })
} else if (!(key in rightObj)) {
result.push({ path: childPath, type: 'removed', left: leftObj[key] })
} else {
diffValues(leftObj[key], rightObj[key], childPath, result)
}
}
return
}
if (Array.isArray(left) && Array.isArray(right)) {
const len = Math.max(left.length, right.length)
for (let i = 0; i < len; i++) {
const childPath = `${path}[${i}]`
if (i >= left.length) {
result.push({ path: childPath, type: 'added', right: right[i] })
} else if (i >= right.length) {
result.push({ path: childPath, type: 'removed', left: left[i] })
} else {
diffValues(left[i], right[i], childPath, result)
}
}
return
}
result.push({ path, type: 'changed', left, right })
}
export function diffJson(leftStr: string, rightStr: string): Result<DiffEntry[]> {
try {
const left = JSON.parse(leftStr)
const right = JSON.parse(rightStr)
const result: DiffEntry[] = []
diffValues(left, right, '', result)
return { ok: true, output: result }
} catch (e) {
return { ok: false, error: `JSONパースエラー: ${(e as Error).message}` }
}
}よくある使用例・注意点
03APIレスポンスの変更確認
バックエンドのAPIレスポンスが仕様変更されたとき、変更前後のレスポンスをここに貼り付けると、追加・削除・変更されたフィールドを一覧で確認できます。
設定ファイルの比較
JSON形式の設定ファイル(package.json、tsconfig.json など)を比較するのに便利です。本番環境と開発環境の設定差異を素早く把握できます。
キー順序の違いは無視
このツールはキーの順序に関係なく、同じパスに同じ値があれば unchanged として扱います。
{"a":1,"b":2} と {"b":2,"a":1} は差分なしと判定されます。配列の比較はインデックスベース
配列の比較はインデックス(位置)ベースで行います。配列の要素が並び替えられた場合、全要素が changed として表示される場合があります。配列の順序変化を正確に検出したい場合は、並び替え後に比較することをお勧めします。
プライバシーについて
入力したJSONはブラウザ内のみで処理されます。サーバーには一切送信されないため、認証情報や個人情報を含むJSONも安全に比較できます。
関連ツール
04ソースコード
05このツールのソースコード(テストコードを含む)はGitHubで公開しています。 MITライセンスで自由に利用・改変できます。
GitHub でコードを見る →