Code-point vs natural order
{"b": 1, "B": 2, "a10": 3, "a2": 4, "_id": 5}
{"B":2,"_id":5,"a10":3,"a2":4,"b":1}
{"_id":5,"a2":4,"a10":3,"B":2,"b":1}
Sorting JSON keys in code
jq -S . data.json
import json
json.dumps(data, sort_keys=True, indent=2)
const sortKeys = (v) =>
Array.isArray(v) ? v.map(sortKeys)
: v && typeof v === 'object'
? Object.fromEntries(Object.keys(v).sort().map((k) => [k, sortKeys(v[k])]))
: v;
JSON.stringify(sortKeys(data), null, 2);
// Note: integer-like keys ("1", "10") are always listed first by JavaScript, whatever order you insert them in.
Comparing two JSON files? The JSON diff ignores key order on its own. To format without reordering, use the JSON formatter.
Frequently asked questions
Why sort JSON keys?
Object key order has no meaning in JSON, but it matters to people and tools. Sorted keys make two versions of a file easy to compare in a diff, keep generated files (translations, lockfiles, fixtures) stable in version control, and give the same bytes for the same data, which is needed when you hash or sign JSON.
Which order is used?
By default, Unicode code-point order, the same as jq -S, Python’s json.dumps(sort_keys=True) and Go’s encoding/json: uppercase letters come before lowercase, and “a10” before “a2”. Tick “Natural, case-insensitive” for the order a person would expect: case is ignored and numbers inside keys are compared by value.
Are arrays sorted too?
Not by default, because array order usually matters: [first, second] is different data from [second, first]. Objects inside arrays still get their keys sorted. Tick “Sort arrays of values” to sort arrays that contain only strings and numbers (numbers first, by value); arrays of objects always keep their order.
Does sorting change any values?
No. Only the order of keys changes. Numbers are copied exactly as written, so 9007199254740993 and 1.10 aren’t rounded the way JSON.parse would round them, and strings keep their escapes’ meaning.