How to sort JSON keys
July 29, 2026 · 12 min read
Object key order is insignificant to JSON parsers but very significant to Git, checksums, and string equality tests. Two logically identical documents can produce different SHA-256 hashes because keys were inserted in different orders. Sorting keys is the cheapest way to canonicalize objects before diffing or signing.
Sorting is not free intellectually: arrays may be order-sensitive, and some APIs treat JSON objects as ordered maps for backward compatibility (rare). Apply recursive key sorting to objects only unless your contract says otherwise.
Why sorted keys help
Stable ordering makes snapshot tests reliable, reduces noise in audit diffs, and helps cache keys derived from JSON bodies. Payment and identity systems sometimes require canonical JSON before HMAC signatures.
Teams debugging webhook retries see fewer false alarms when compare tools sort both sides automatically. Document that behavior so nobody assumes wire format preserves key order.
Recursive sorting
Walk the tree: at each object, sort keys lexicographically (UTF-16 code units in JavaScript; be aware of locale if you use locale-aware sorts elsewhere). Recurse into nested objects and into array elements that are objects.
Do not sort array elements unless they represent unordered sets and your domain agrees. For arrays of primitives, sorting changes meaning (event timelines).
function sortKeysDeep(v) {
if (Array.isArray(v)) return v.map(sortKeysDeep);
if (v && typeof v === "object") {
return Object.fromEntries(
Object.keys(v).sort().map((k) => [k, sortKeysDeep(v[k])])
);
}
return v;
}
Canonical JSON and hashes
Canonicalization may also fix number formatting and whitespace. JCS (JSON Canonicalization Scheme) goes further than key sorting alone. If you interoperate with cryptography libraries, follow their spec exactly - do not invent a partial canonical form.
After sorting, stringify with a fixed separator policy (no extra spaces vs consistent spacing) before hashing. Changing stringify options breaks signatures even if parsed values match.
When not to sort
Skip sorting when producing responses for clients that display key order for UX (debug panels) or when working with JSON objects used as ordered lists in legacy systems. In those cases, compare semantically instead of bytewise.
Large documents: sorting allocates new objects. For multi-hundred-MB payloads, stream or process subtrees in pipelines rather than cloning entire trees in memory.
Pipeline integration
Add a sort step before compare, hash, and S3 etag-style checks. Log the canonical string length, not the raw body, when investigating cache mismatches.
Combine with pretty print for humans and compact stringify for hashes - two outputs from one parse, two audiences served.
FAQ
- Does sorting JSON keys change the data?
- No for semantics under the JSON object model. Yes for raw string or hash comparisons without sorting.
- Should I sort arrays too?
- Only when arrays represent unordered sets by contract. Default is to leave array order untouched.
- Is sorted JSON the same as canonical JSON?
- Canonicalization may include additional rules beyond key order. Check your crypto or compliance spec.
- Which sort order should I use?
- Lexicographic Unicode code point order is the usual choice for cross-language consistency.