JSON-diff
Порівняйте два JSON-документи й побачте, які саме поля додано, видалено чи змінено
JSON A (зліва / до)
JSON B (справа / після)
JSON-diff
Порівняйте два JSON-документи й побачте, які саме поля додано, видалено чи змінено
Можливості
- Структурний diff між двома JSON-значеннями — обʼєкти, масиви та примітиви правильно обходяться (null трактується як скаляр, а не обʼєкт; баг typeof null виправлено)
- Кожна різниця звітується як шлях RFC 6901 JSON Pointer (напр. `/users/0/email`), щоб одразу перейти до точного вузла у вкладених даних
- Змінені записи показують значення «до» І «після» поруч, тож відразу зрозуміло, чи 'active' перейшов із true→false, чи змінилося число
- Зведення: додано, видалено, змінено та незмінні листки — масштаб diff одним поглядом перед читанням деталей за шляхами
- Окремий звіт про помилку розбору з кожного боку називає, який ввід не розібрався, і містить повідомлення JavaScript-движка — не доводиться вгадувати, A чи B пошкоджений
- Кнопка «Копіювати звіт» видає весь diff (секції «Додано» / «Видалено» / «Змінено» плюс лічильник незмінних) як простий текст — вставляйте в код-рев'ю або повідомлення коміту
- «Завантажити приклад» заповнює обидві панелі маленьким реалістичним прикладом (запис користувача зі змінами ролі + адреси), нові користувачі бачать diff без набирання тексту
- Повністю на стороні клієнта: JSON A і JSON B розбираються та порівнюються у вашому браузері; нічого не завантажується, інструмент працює офлайн після завантаження сторінки
Як використовувати
- Вставте JSON «до» в ліве текстове поле (JSON A), JSON «після» — в праве (JSON B).
- Клацніть «Порівняти». Diff обчислюється рекурсивно: обʼєкти — за ключем, масиви — за індексом.
- Прочитайте зведення: скільки ключів додано, видалено, змінено та скільки листків збіглося.
- Прокрутіть списки шляхів, щоб побачити, які шляхи JSON Pointer змінилися; змінені рядки показують «до» → «після».
- Натисніть «Копіювати звіт», щоб отримати весь diff простим текстом — корисно для нотаток рев'ю, баг-репортів і повідомлень комітів.
- Використайте «Завантажити приклад», щоб побачити робочий приклад перед вставленням своїх даних.
Поради та найкращі практики
- Спершу проженіть обидві сторони через JSON Formatter, якщо хочете, щоб текстовий diff також вважав структурно рівні документи без змін.
- Для великих масивів, де важливий порядок, цей інструмент підходить ідеально; для множин — попередньо сортуйте за стабільним ключем.
- Вивід шляху — RFC 6901, його можна передати безпосередньо в бібліотеки на кшталт fast-json-patch для програмного застосування змін.
- Вставляйте звіт у описи PR, щоб показати рев'юерам, що саме змінилося у JSON конфігу чи фікстури.
- Якщо помилки розбору вказують на конкретну колонку, повідомлення движка часто містить рядок/колонку у парсерів типу json5 — тут же використовується суворий JSON.parse, тож рядок/колонка — від хоста.
Запитання та відповіді
Як порівнюються масиви — за індексом чи за значенням?
За індексом. Елемент 0 A порівнюється з елементом 0 B, 1 з 1 і т. д. Якщо A довший, зайві хвостові індекси звітуються як «Видалено»; якщо B довший — як «Додано». Швидко й передбачувано, але одиничне вставлення на початку великого масиву каскадує у багато «змінено». Для нечутливих до порядку порівнянь (множини унікальних ID) спершу відсортуйте обидва масиви або перетворіть на обʼєкти з ключем-ідентифікатором.
Яка нотація шляхів у результаті?
RFC 6901 JSON Pointer: шляхи — це токени, розділені слешами, що спускаються деревом JSON. `/users/0/email` означає «властивість email елемента 0 у users». Ключі з `~` екрануються як `~0`, слеші — `~1`. Сам корінь — `/`. Та сама нотація використовується в патч-інструментах, JSON Schema instancePath і підказці вказівника json-formatter.
Як обробляється null?
null трактується як листове значення, не обʼєкт — хоча у JavaScript typeof null === 'object'. Тож {a: null} vs {a: {}} показується як змінене, а не рекурсує в порожній обʼєкт. {a: null} vs {a: null} — один незмінний листок, а {a: null} vs {a: 0} — змінене з «до=null після=0».
Чи diff працює з ключами зі спеціальними символами?
Так. Ключі з крапками, слешами, дужками чи тільдами екрануються за JSON Pointer у виводі шляху — `~` стає `~0`, `/` — `~1`. Тож ключ із буквальною назвою `a/b` показується як `/a~1b` — однозначно зворотно.
Чому лічильник незмінних не відповідає моїм очікуванням?
Незмінні рахуються на рівні ЛИСТКІВ — примітиви, рівні між A і B. Глибоко вкладений обʼєкт, чиє піддерево повністю ідентичне, дає по одній незмінній записі на листок, а не одну на все піддерево. Це робить лічильник справжньою перевіркою: «скільки примітивних значень залишилось».
Що якщо одна сторона null або порожня?
Порожній ввід парситься як null (тож `{a:1}` vs порожньо порівнюється з null і весь обʼєкт позначається як доданий). Літеральний `null` — валідний JSON-документ; порівняння двох null дає нуль доданих/видалених/змінених і один незмінний. Якщо обидва ввíди порожні — diff тривіально нульовий усюди.
Мій JSON кудись надсилається?
Ні. Обидва текстові поля залишаються у вашому браузері; diff працює в тому ж JavaScript-контексті, що й сторінка. Вкладка «Мережа» у DevTools не показує запитів при натисканні «Порівняти». Інструмент працює офлайн після кешування сторінки.
Чим це відрізняється від порядкового текстового diff?
Текстовий diff на кшталт `diff a.json b.json` працює із символами та переносами рядків: переформатуєте ті ж дані — він засвітиться. Це СТРУКТУРНИЙ diff: `{"a":1, "b":2}` та `{"b":2, "a":1}` ідентичні (нуль diff). Також не зважає на відступи, кінцеві пробіли та стилі коментарів. Використовуйте текстовий diff, коли важливе форматування; цей — коли важливі дані.