Skip to content

Feature request: sort_keys option for deterministic JSON output #437

@s-celles

Description

@s-celles

Summary

It would be very useful if JSON.json and JSON.print supported a sort_keys keyword argument to produce deterministic JSON output with alphabetically sorted dictionary keys.

Motivation

Julia's Dict has non-deterministic iteration order that can vary across Julia versions, platforms, and even runs. When serializing Dict values with JSON.json, the key order in the output is unpredictable.

This causes real problems for:

  • Snapshot/regression testing — HTML or JSON output containing serialized dicts differs between CI environments (e.g., Julia LTS vs nightly, Linux vs macOS) purely due to key ordering, causing spurious test failures.
  • Reproducibility — deterministic output is expected for caching, diffing, and version control of generated artifacts.
  • Interoperability — many JSON libraries in other languages (Python's json.dumps(sort_keys=True), JavaScript's custom replacers, Go's encoding/json) provide this capability.

Proposed API

# Keyword argument on existing functions
JSON.json(d; sort_keys=true)
JSON.print(io, d; sort_keys=true)

Current workaround

We currently have to implement a recursive helper function:

function sorted_json(d::AbstractDict)
    io = IOBuffer()
    write(io, "{")
    for (i, k) in enumerate(sort(collect(keys(d))))
        i > 1 && write(io, ",")
        JSON.print(io, k)
        write(io, ":")
        v = d[k]
        if v isa AbstractDict
            write(io, sorted_json(v))
        else
            JSON.print(io, v)
        end
    end
    write(io, "}")
    return String(take!(io))
end

This works but duplicates serialization logic that belongs in the library.

Context

We encountered this while developing JSXGraph.jl, where HTML snapshot tests failed across Julia versions/platforms solely due to Dict key ordering in JSON.json output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions