Comparateur JSON, gratuit

Comparez deux objets JSON et visualisez les différences mises en évidence.

Aucune donnée ne quitte votre appareil

À propos de la comparaison JSON

La comparaison JSON (également appelée diff JSON) identifie les différences entre deux structures JSON. Contrairement à un diff de texte brut, une comparaison qui comprend le JSON connaît les clés et les valeurs, et peut donc vous indiquer exactement quelles propriétés ont été ajoutées, supprimées ou modifiées · indépendamment de l'ordre des clés.

Cet outil effectue une comparaison profonde et récursive de deux objets JSON. Il gère les objets imbriqués, les tableaux, les chaînes, les nombres, les booléens et les valeurs null. Tout le traitement se fait localement dans votre navigateur.

Une brève histoire de JSON

La biographie de JSON est plus courte que celle du langage de programmation moyen et beaucoup moins dramatique. L'acronyme est né chez State Software, Inc., une petite société que Douglas Crockford et Chip Morningstar ont fondée en mars 2001 pour construire ce qu'on appellerait plus tard des applications web Ajax. Le premier message JSON a été envoyé en avril 2001, depuis un ordinateur dans le garage Bay-Area de Morningstar. Crockford ne revendique pas avoir inventé JSON, il l'a isolé de la syntaxe des objets littéraux JavaScript, lui a donné un nom et a monté un site web. Il a acquis json.org en 2002 et y a publié une grammaire en diagramme ferroviaire. Pendant quatre ans, JSON s'est propagé par bouche-à-oreille et un mince filet d'implémentations de bibliothèques. En décembre 2005, Yahoo! a commencé à proposer certains de ses services web en JSON, le moment que la plupart des historiens désignent comme l'entrée de JSON dans le mainstream. La normalisation est venue par vagues : RFC 4627 (juillet 2006), rédigée par Crockford lui-même, avec un statut informationnel plutôt que standards-track ; ECMA-404 première édition (octobre 2013) ; RFC 7159 (mars 2014), qui a mis JSON sur le Standards Track de l'IETF et a assoupli l'exigence selon laquelle la valeur de plus haut niveau devait être un objet ou un tableau. Les versions actuelles sont RFC 8259 (décembre 2017), désormais Internet Standard STD 90, et ECMA-404 deuxième édition (décembre 2017). Les deux sont intentionnellement identiques en grammaire ; le texte IETF ajoute des directives de sécurité et d'interopérabilité que le texte Ecma omet délibérément.

Deux familles algorithmiques : diff par ligne et diff structurel

L'informatique réfléchit aux diffs depuis les années 1970. Douglas McIlroy (le même McIlroy qui a inventé les pipes Unix) et James W. Hunt ont écrit le diff Unix original au début des années 1970 ; il a été livré dans la 5e édition d'Unix en 1974, avec l'algorithme sous-jacent documenté dans le Bell Labs Computing Science Technical Report #41 en juin 1976. Hunt-McIlroy se base sur le problème de la plus longue sous-séquence commune : trouver la plus longue séquence de lignes qui apparaît dans l'ordre dans les deux entrées, et tout ce qui n'est pas dans cette séquence est soit une suppression soit une insertion. Une décennie plus tard, Eugene W. Myers publie « An O(ND) Difference Algorithm and Its Variations » dans Algorithmica Vol 1, Issue 2 (1986), reformulant le problème comme une recherche de plus court chemin sur un « graphe d'édition », base d'une implémentation Unix diff plus rapide qui tournait deux à quatre fois plus vite que son prédécesseur. Aujourd'hui, git diff utilise par défaut un algorithme histogramme de LibXDiff, généralement plus rapide que Myers et produisant une sortie plus lisible, particulièrement autour des blocs déplacés. Patience diff (Bram Cohen, 2008) est un autre raffinement LCS qui privilégie les lignes d'ancrage uniques. Toutes des variations sur un thème : LCS ligne par ligne, traitant l'entrée comme une séquence plate de tokens opaques. Aucun ne sait ce qu'est JSON.

La famille des diffs structurels adopte une approche différente : parcourir les deux entrées en parallèle, comparer les primitives par égalité stricte, calculer l'union des clés d'objet (présent-à-gauche-seulement est « supprimé », présent-à-droite-seulement est « ajouté », présent-dans-les-deux signifie récursion), et parcourir les tableaux par index. Pour chaque position, récursion. Si un tableau est plus long, les éléments supplémentaires sont ajoutés ou supprimés. Les changements de type (nombre vs chaîne, objet vs tableau) deviennent des entrées « type changé ». C'est l'algorithme que jsondiffpatch implémente comme cas de base, et c'est l'algorithme que cet outil implémente. Sa force est que la sortie a du sens : chaque changement rapporté a un chemin dans le document (user.address.city, items[3].price) et une sémantique claire. Sa faiblesse est la troisième étape, la comparaison de tableaux par index, qui produit du non-sens dès qu'un élément est inséré près du début d'un long tableau.

Le problème le plus dur du diff JSON : les tableaux

Supposons que votre JSON « avant » contienne le tableau ["alpha", "beta", "gamma", "delta"] et que votre JSON « après » contienne ["alpha", "new", "beta", "gamma", "delta"]. Un diff naïf basé sur l'index rapporte quatre changements : index 1 passé de « beta » à « new » ; index 2 passé de « gamma » à « beta » ; index 3 passé de « delta » à « gamma » ; index 4 ajouté « delta ». Un humain regardant cela dirait qu'il y a un changement : une seule insertion à l'index 1. C'est le même problème LCS que la famille des diffs par ligne a résolu dans les années 1970, appliqué à des tableaux de valeurs JSON plutôt qu'à des tableaux de lignes de texte. jsondiffpatch fait exactement cela, calcule le LCS des deux tableaux et émet des insertions et suppressions relatives à celui-ci. Pour les tableaux de primitives ça marche bien. Pour les tableaux d'objets non : [{id: 1, name: "Alice"}] versus [{id: 1, name: "Alicia"}] n'ont aucune sous-séquence commune par égalité de référence, donc le LCS naïf rapporte « supprimer tout l'élément de gauche, ajouter tout l'élément de droite » alors que la vérité est qu'un champ d'un élément a changé. La solution de jsondiffpatch est le callback objectHash : l'appelant fournit une fonction qui mappe chaque objet à une clé d'identité (typiquement obj => obj.id), et le diff fait correspondre les éléments du tableau par identité plutôt que par référence. C'est un problème général difficile que personne n'a complètement résolu. L'outil Absolutool, selon sa propre FAQ, compare les tableaux par index, il n'implémente ni LCS ni objectHash. C'est un choix de portée délibéré pour un petit outil gratuit : il est excellent pour les diffs d'objets et plus faible sur les tableaux où des éléments ont été insérés ou réordonnés.

JSON Patch (RFC 6902) : les diffs comme format de transport

RFC 6902, « JavaScript Object Notation (JSON) Patch », a été publiée en avril 2013. Elle définit le type de média application/json-patch+json et un langage de patch à six opérations : add, remove, replace, move, copy, test. Un patch est lui-même un document JSON, un tableau d'objets opération, chacun avec une clé op, une clé path (un JSON Pointer vers l'emplacement cible) et un champ valeur ou from selon le cas. Les opérations sont appliquées dans l'ordre, atomiquement : si l'une échoue, tout le patch est rejeté. La syntaxe du chemin vient de RFC 6901, « JSON Pointer », un document compagnon publié le même mois, une minuscule syntaxe de chaîne de tokens de référence séparés par des barres obliques (/user/address/city signifie « la valeur à la clé city à l'intérieur de address à l'intérieur de user » ; /items/3 signifie « le quatrième élément de items », indexé à zéro). Parce que / et ~ sont spéciaux, ils sont échappés en ~1 et ~0 respectivement (dans cet ordre, décoder ~1 en premier pour éviter les bugs de double-décodage). JSON Patch est le bon format de sortie pour un outil de diff JSON qui veut alimenter le résultat à une autre machine. La méthode HTTP PATCH (RFC 5789) a été conçue exactement pour ce genre de charge utile de mise à jour partielle. Kubernetes supporte RFC 6902 aux côtés de son propre format strategic-merge-patch. Cet outil n'émet pas actuellement de JSON Patch, c'est une direction de fonctionnalité future, pas actuelle.

JSON Merge Patch (RFC 7396) : l'alternative plus simple, avec perte

RFC 7396, « JSON Merge Patch », a été publiée en octobre 2014 par Paul Hoffman et James Snell. Elle n'utilise aucune opération, le document patch est simplement un objet JSON partiel qui se superpose à l'original. Tout champ présent dans le patch écrase le champ correspondant dans l'original ; tout champ mis à null dans le patch supprime ce champ ; tout champ absent du patch reste inchangé ; les tableaux sont remplacés en gros, jamais fusionnés. Merge Patch est concis et facile à écrire à la main. Le compromis est la perte d'expressivité : aucun moyen de mettre la valeur d'un champ à null littéral (parce que null signifie « supprimer ») ; aucun moyen de modifier un seul élément d'un tableau (tout le tableau est remplacé) ; aucun moyen d'exprimer un move ou un copy ; aucun moyen de distinguer « je n'ai pas touché à ce champ » de « je veux le mettre à sa valeur actuelle ». Pour la plupart des mises à jour quotidiennes d'API, ces limitations sont acceptables, c'est pourquoi Merge Patch est le plus populaire des deux formats. RFC 6902 gagne dans les scénarios où l'une des limitations mord. Kubernetes utilise les deux formats délibérément, choisissant le bon pour chaque contexte.

Comment le diff visuel se rend

Il existe trois conventions visuelles courantes pour afficher un diff structurel. Côte à côte, deux colonnes, original à gauche, modifié à droite, avec les lignes correspondantes alignées (la mise en page que cet outil utilise pour ses entrées). Diff unifié inline, une seule colonne montrant les lignes supprimées (typiquement préfixées par - et colorées en rouge), les lignes ajoutées (+, vert) et les lignes de contexte inchangées (pas de préfixe, texte simple), la mise en page que git diff utilise par défaut. Vue arbre, rendre le JSON comme un arbre repliable, avec les nœuds modifiés mis en évidence et les nœuds inchangés repliés. Les conventions de couleur sont remarquablement constantes dans l'écosystème : vert pour les ajouts, rouge pour les suppressions, jaune ou ambre pour les valeurs modifiées, gris neutre pour les inchangées. Cet outil suit la convention exactement : vert clair pour les ajouts, rouge clair pour les suppressions, jaune clair pour les changements. La plupart des utilisateurs reconnaîtront les couleurs depuis GitHub, GitLab, BitBucket, toutes les vues diff d'IDE et des dizaines d'outils en ligne.

Utilisations courantes

Cas limites à connaître

Précision numérique. RFC 8259 dit que les nombres JSON sont à précision arbitraire et ne met aucune limite supérieure au nombre de chiffres. JavaScript, cependant, parse chaque nombre comme un double IEEE 754 64 bits. Au-dessus de Number.MAX_SAFE_INTEGER (253 − 1 = 9 007 199 254 740 991), les entiers peuvent perdre silencieusement de la précision en aller-retour à travers un diff basé sur JavaScript. Le même problème affecte la virgule flottante, 0.1 + 0.2 n'est célèbrement pas exactement 0.3 en IEEE 754. JSON strict interdit aussi les virgules finales et les commentaires ; les deux sont des erreurs de syntaxe selon RFC 8259. JSON5 (json5.org) est un sur-ensemble formel permettant commentaires, virgules finales, apostrophes, clés non quotées, nombres hex, points décimaux en début/fin et Infinity/NaN. JSONC est le mode « JSON with Comments » de Microsoft utilisé dans les fichiers de réglages de VS Code. Cet outil utilise JSON.parse() et rejettera donc les deux, retirez commentaires et virgules finales avant de coller.

Chaînes de date. JSON n'a pas de type date natif. Les dates sont typiquement encodées comme chaînes, le standard de facto étant ISO 8601 (et spécifiquement le profil RFC 3339 que la plupart des API internet utilisent) : YYYY-MM-DDTHH:MM:SS[.fff]Z. Un diff qui compare les dates comme chaînes rapportera 2024-01-01T00:00:00Z et 2024-01-01T00:00:00.000Z comme différentes, alors qu'elles représentent le même instant, parce que les chaînes diffèrent. Clés dupliquées. RFC 8259 §4 énonce « les noms dans un objet DEVRAIENT être uniques », le DEVRAIENT est normativement plus faible que DOIVENT. Le JSON.parse() de JavaScript accepte les clés dupliquées et garde silencieusement la dernière ; d'autres parseurs peuvent garder la première ou lever une erreur. null vs manquant. {"a": null} et {} sont des valeurs JSON différentes. Cet outil rapporte le premier comme « la clé a a la valeur null » et le second comme « pas de clé a », ils sont correctement distingués. Le traitement de null par JSON Merge Patch comme signal de suppression est un aveu au niveau du format que la distinction est réelle et délicate.

L'écosystème en 2026

Le diff JSON open-source est dominé par une poignée de bibliothèques. jsondiffpatch de Benjamin Eidelman, publié pour la première fois en 2012, est la bibliothèque JavaScript de facto : ~5k étoiles GitHub, supporte objectHash, les tableaux LCS, les patchs inverses et un formateur HTML visuel. json-diff d'Andrey Tarantsov est l'outil CLI Node canonique, avec le même nom partagé par des implémentations parallèles en Python, Go et Rust. DeepDiff de Sep Dehpour est la bibliothèque Python dominante, diff récursif avec options pour ignorer l'ordre, ignorer les changements de type numérique, et toute une foule de contrôles fins. Le diff JsonNode de Jackson (Java) à la Linux Foundation est le choix standard JVM. jq n'a pas de commande diff native mais sa famille d'opérateurs = et // peut exprimer des comparaisons structurelles simples. Le diff intégré de VS Code gère JSON via le mode texte ; l'extension JSON Tools ajoute la comparaison JSON-aware. Des outils en ligne comme Diffchecker proposent des modes JSON qui sont essentiellement le même parcours récursif que cet outil implémente, souvent superposé aux mêmes bibliothèques.

Pourquoi le tout-navigateur compte ici

Differ deux payloads JSON sur un serveur exige de téléverser les deux. Pour des exemples ordinaires de données publiques, c'est inoffensif. Pour des réponses d'API contenant des tokens d'authentification, des PII clients, des dossiers d'employés internes, des secrets de configuration ou des données produit non publiées, ce ne l'est pas. Même après que le diff est terminé, ces payloads restent dans les logs serveur, possiblement dans un cache CDN, possiblement dans un pipeline d'analytique, possiblement dans une sauvegarde. Un diff tout-navigateur ne transmet jamais, le JSON est parsé et parcouru entièrement dans votre onglet. Vous pouvez vérifier en ouvrant l'onglet Network de DevTools en cliquant Compare ; il n'y a aucune requête sortante. Pour comparer des réponses d'API contre une base, déboguer une dérive de configuration entre environnements, ou auditer des changements dans un lockfile qui contient des URLs de paquets internes, « le JSON ne quitte jamais mon appareil » est l'architecture qui rend l'outil sûr à utiliser sur de vraies données de production.

Questions fréquentes

L'ordre des clés affecte-t-il la comparaison ?

Non. Les objets JSON sont non ordonnés selon la spécification, donc {"a":1, "b":2} et {"b":2, "a":1} sont traités comme identiques. Seules les différences réelles de valeurs sont signalées.

Comment les tableaux sont-ils comparés ?

Les tableaux sont comparés par index. Si le tableau à l'index 2 diffère entre les deux entrées, cet index spécifique est signalé. Les éléments ajoutés ou supprimés en fin de tableau sont aussi détectés.

Que se passe-t-il avec des objets profondément imbriqués ?

La comparaison est entièrement récursive. Les objets et tableaux imbriqués à n'importe quelle profondeur sont comparés propriété par propriété. La sortie affiche le chemin complet de chaque différence (par ex. « user.address.city »).

Pourquoi ma comparaison de grands entiers paraît-elle fausse ?

JavaScript parse chaque nombre JSON comme un double IEEE 754 64 bits. Au-dessus de Number.MAX_SAFE_INTEGER (253 − 1 = 9 007 199 254 740 991), les entiers peuvent perdre silencieusement de la précision. Donc un fichier JSON contenant 9007199254740993 peut comparer comme identique à un fichier contenant 9007199254740992. C'est une limitation de la représentation numérique sous-jacente, pas de l'outil de diff. Si vous diffez des données contenant des IDs 64 bits (IDs snowflake Twitter, IDs Discord, grandes clés de base de données), faites en sorte que votre sérialiseur les émette comme chaînes plutôt que comme nombres. La comparaison de virgule flottante a la même mise en garde : 0.1 + 0.2 n'est célèbrement pas exactement 0.3 en IEEE 754.

Puis-je comparer du JSON5 ou JSONC (JSON avec commentaires) ?

Pas directement. Cet outil utilise le JSON.parse() intégré du navigateur, qui suit strictement RFC 8259, commentaires, virgules finales, chaînes entre apostrophes et clés non quotées sont des erreurs de syntaxe. Si votre entrée est JSON5 (json5.org) ou JSONC à la VS Code, retirez d'abord les commentaires et virgules finales, ou passez-le par un outil comme jsonc-parser pour convertir en JSON strict avant de coller.

Mon JSON est-il envoyé à un serveur ?

Non. La comparaison tourne entièrement dans votre navigateur via JavaScript. Le JSON collé ne traverse jamais le réseau, vérifiez dans l'onglet Network de DevTools en cliquant Compare, ou mettez la page hors ligne après chargement et confirmez que le diff fonctionne encore. Sûr pour comparer des réponses d'API avec tokens d'authentification, des fichiers de configuration avec secrets, ou des exports de base de données contenant des PII clients.

Outils associés