Comparing Command-Line JSON Pretty Printers

November 7, 2013

Trying to read badly-formatted JSON is just a waste of time. On the command-line, or in your text editor with filtering, there are tools that will fix your JSON and make everything right.

There are many options and none are perfect, let’s review our choices:

JSON tool comparison

(click to enlarge)

Input Files

The worst-case is what I used: a mix of strings, numbers and booleans without any human-friendly spaces or alignment.

sample.json:

{"first":"Jimmy","last":"James","age":29,"sex":"M","salary":63000,"registered":false}

The ideal output is the following:

{
  "first": "Jimmy",
  "last": "James",
  "age": 29,
  "sex": "M",
  "salary": 63000,
  "registered": false
}

I also thought it would be interesting to see how pretty-printers would react to invalid JSON. I took sample.json and changed a few things.

invalid.json:

{"first":Jimmy","last":"James","age":29,"sex":"M","salary":63000"registered":false}

Can you spot (all) the mistakes? That’s my point – you don’t have to – that’s what computers are for.

Discussion: python -m json.tool

Use the json.tool module from python which will pretty-print STDIN by default.

# cat sample.json | python -m json.tool
{
    "age": 29,
    "first": "Jimmy",
    "last": "James",
    "registered": false,
    "salary": 63000,
    "sex": "M"
}
# cat invalid.json | python -m json.tool
No JSON object could be decoded

pros

cons

Discussion: YAJL

YAJL is written in C and can be installed with your favorite package manager. The command you want to use is json_reformat.

# cat sample.json | json_reformat
{
    "first": "Jimmy",
    "last": "James",
    "age": 29,
    "sex": "M",
    "salary": 63000,
    "registered": false
}
# cat invalid.json | json_reformat
lexical error: invalid char in json text.
                                        {"first":Jimmy","last":"James"
                     (right here) ------^

pros

cons

Discussion: jq

jq is written in C and can be installed with your favorite package manager.

# cat sample.json | jq .
{
  "registered": false,
  "salary": 63000,
  "sex": "M",
  "age": 29,
  "last": "James",
  "first": "Jimmy"
}
# cat invalid.json | jq .
parse error: Invalid numeric literal at line 1, column 15

pros

cons

Discussion: jsonlint

jsonlint is an NPM package: npm install -g jsonlint.

# cat sample.json | jsonlint
{
  "first": "Jimmy",
  "last": "James",
  "age": 29,
  "sex": "M",
  "salary": 63000,
  "registered": false
}
# cat invalid.json | jsonlint
[Error: Parse error on line 1:
{"first":Jimmy","last":"James
---------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined']

pros

cons

Discussion: jsontool

jsontool is an NPM package: npm install -g jsontool. The command you want to use is json.

# cat sample.json | json
{
  "first": "Jimmy",
  "last": "James",
  "age": 29,
  "sex": "M",
  "salary": 63000,
  "registered": false
}
# cat invalid.json | json
json: error: input is not JSON: Unexpected 'J' at line 1, column 10:
        {"first":Jimmy","last":"James","age":29,"sex":"M","salary":63000"registered":false}
        .........^
{"first":Jimmy","last":"James","age":29,"sex":"M","salary":63000"registered":false}

pros

cons

Conclusion

I used to install YAJL but now, since I always install node.js and NPM, I skip it.

Here’s what I used to recommend:

However, now that I have compiled this grid, I would use jsonlint instead of jsontool. I always install jsonlint anyway, because that’s what syntastic integrates with – I just had not realized that the output of both jsonlint and jsontool is equivalent.

Discuss on Twitter