How to compare JSON files ignoring key order and formatting
An API returns the same object with its keys in another order. A config file was reformatted by an editor. Two environments dump their settings and you need to know whether they really differ. In each case a text diff is full of changes and almost none of them are real.
What is and isn't a change in JSON
By the JSON specification, an object is an unordered collection of name/value pairs, so:
- Key order is not a change.
{"a":1,"b":2}and{"b":2,"a":1}are the same object. - Formatting is not a change. Minified, indented with two spaces or with four: same value.
- Array order is a change. An array is an ordered list:
[1,2]is not[2,1]. - Types are a change.
"8080"is a string and8080a number;trueis not1. A service that reads one may choke on the other.
The command-line way: sort with jq
jq can rewrite both files with their keys sorted and the same indentation, and then a normal
diff works:
diff <(jq -S . old.json) <(jq -S . new.json)
-S sorts the keys of every object, recursively, and . pretty-prints the result, so
both files end up in the same canonical shape. It is a good trick for one pair of files; for a folder of them,
or for someone without jq at hand, it gets tedious.
Comparing JSON in Kotej
Kotej's JSON diff parses both files and compares the values: objects key by key in any order, arrays in order, and types strictly. The verdict says whether the files are identical, equivalent (same data, different formatting or key order) or different, and when they differ you see the changed lines side by side, unified, or word by word.
Files are read in your browser and never uploaded, which matters when the JSON is an API response with real customer data or a config full of secrets.
Comparing configs across environments
For whole sets of files, dump the configuration of each environment into a folder and compare the two folders: every JSON file is compared by structure, XML files as XML, and the rest as text, and the tree shows at a glance which files differ and which exist in only one environment.
One JSON object per line is a log
A file with one JSON object per line (JSON Lines, the format of many structured loggers) is not one JSON document. Kotej detects it and compares it as a log, entry by entry, without the timestamps and IDs that make every line unique. See comparing logs of two pods.
Kotej