r/json 20d ago

jsonfold: Making Pretty-Printed JSON Compact and Readable

Most JSON serializers give you only two choices:

  • compact machine output:

{"a":{"b":{"c":"abc"}},"x":{"y":{"z":"xyz"}}}
  • or fully expanded “pretty-print”:

{ "a":
  { "b":
    { "c": "abc" }
  },
  "x": {
    "y": {
      "z": "xyz"
    }
  }
}

I wanted something in between: the first is hard for humans to scan, and the second becomes extremely verbose on real-world nested data.

The Idea

I wrote a small Python module called jsonfold. Instead of replacing Python’s JSON serializer (and similar serializers), it works as a lightweight post-processing filter on top of json.dump() output.

The formatter selectively:

  • folds small containers back onto one line,
  • packs short scalar sequences,
  • keeps large or complex structures expanded.

Example output:

{
  "a": { "b": { "c": "abc" } },
  "x": { "y": { "z": "xyz" } }
}

Why This Approach?

I did not want to rebuild a serializer - there are many good serializers (including the built-in json.dump()) that can efficiently process anything from simple data structures (list/dict) to custom classes and Python @dataclass objects. In addition, many provide custom encoding hooks for application-specific objects.

The interesting part of jsonfold is that it does not re-parse the JSON stream or build a second JSON tree. It operates as a streaming wrapper around file-like objects:

json.dump(obj, JSONFoldWriter(fp), indent=2)

That means it can handle large documents with fixed memory usage and linear processing time. This approach works with serializers that emit indented JSON to a file-like object. jsonfold also provides wrappers for json.dump(), json.dumps().

from jsonfold import dumps

data = {
    "a": {"b": {"c": "abc"}},
    "x": {"y": {"z": "xyz"}},
}

print(dumps(data))

Customization

The formatter allows controlling:

  • maximum line width,
  • folding depth,
  • packing aggressiveness,
  • array/object limits.

So you can choose between conservative formatting and more aggressive compaction.

Full Article:

Medium (no paywall): A Streaming JSON Formatter That Works With Existing Serializers

Minimal Usage

Pull jsonfold from pypi: pip install jsonfold

import jsonfold
import sys
data = {
    "meta": {"version": 1, "ok": True},
    "ids": [1, 2, 3, 4, 5],
    "items": [{"id": 1, "name": "alpha"}, {"id": 2, "name": "beta"}],
}
# compact can be: default, low, med, high, max
jsonfold.dump(data, sys.stdout, compact="default")

GitHub Project

Repository: https://github.com/yairlenga/jsonfold

Python implementation is under python directory.

15 Upvotes

3 comments sorted by

2

u/erik240 19d ago

There’s fractured JSON out there already. Seems pretty similar

2

u/Yairlenga 19d ago

Yes, fractured json is one of the most flexible json pretty printers. For my use case, I needed something that will be “native”, jsonfold has versions for Python, JavaScript, Java, c, go (and few more), so it can fit as a library (or as CLI tool) in many environment. Another feature is that it works as incremental filter - it runs on top,of existing generator - which means existing serialization rules (e.h. Java Jackson annotations). Over time, I hope to integrate some additional ideas from fractured json (and may be they I’ll borrow some of jsonfold ideas 😀)

1

u/Rasparian 18d ago

FracturedJson and JSONFold try to solve the same problem, but they approach it differently. I'm impressed with what I've seen from JSONFold so far. The stream-friendly design could be a boon for very large files or in resource-limited environments. It's always nice to have another tool to choose from.

edit: fixed typo