A Streaming JSON Formatter That Works With Existing Serializers | by Yair Lenga | May, 2026 | MediumSitemapOpen in appSign up<br>Sign in
Medium Logo
Get app<br>Write
Search
Sign up<br>Sign in
A Streaming JSON Formatter That Works With Existing Serializers
Yair Lenga
9 min read·<br>3 days ago
Listen
Share
A Python streaming post-filter for compact, human-readable JSON with configurable formatting behavior.<br>Built-in JSON serializers give us two choices:<br>The default output is built for machines and optimized for efficiency. It is compact, without any extra whitespace. While technically “text”, it feels “binary” — a dense wall of brackets, quotes, commas, and braces that is painful to inspect.<br>Press enter or click to view image in full size
To solve this problem many serializers provide a “Pretty-print” mode, which adds indentation, spacing around tokens and line breaks — making it readable for humans. The problem is that for large documents it often goes too far: A small array of numbers becomes ten lines. A tiny metadata object becomes a block. Deep structures become readable only by making the file much longer.<br>That extra formatting is not free. It makes logs larger, diffs noisier, terminal output harder to scan, and requires “speed-scrolling” to review the data sets.<br>What I wanted was a middle ground: JSON that keeps the shape of pretty-printed output, but folds small, simple structures back onto one line when they fit.<br>This article describes jsonfold, a process for "compacting" pretty-print JSON data to make it more readable for humans. The level of "compactness" is controlled by parameters, and there are a few preset configurations that can be used to get output with minimal effort.<br>jsonfold in 2 minutes<br>Get fine control over the pretty-print JSON output. Keep it machine-readable and human-friendly.
Minimal Usage<br>Pull jsonfold.py from GitHub project<br>import jsonfold<br>import sys<br>data = {<br>"meta": {"version": 1, "ok": True},<br>"ids": [1, 2, 3, 4, 5],<br>"items": [{"id": 1, "name": "alpha"}, {"id": 2, "name": "beta"}],<br># compact can be: default, low, med, high, max<br>jsonfold.dump(data, sys.stdout, compact="default")GitHub Project<br>Repository: https://github.com/yairlenga/jsonfold<br>Python implementation is under python directory.<br>Different levels of compaction<br>// compact=low<br>"a": {<br>"b": { "c": "abc" }<br>},<br>"x": {<br>"y": { "z": "xyz" }<br>}// Compact=default<br>"a": { "b": { "c": "abc" } },<br>"x": { "y": { "z": "xyz" } }<br>}// Compact=max<br>{ "a": { "b": { "c": "abc" } }, "x": { "y": { "z": "xyz" } } }jsonfold on real data.<br>Using the geojson file geojson.xyz: admin 1 states provinces shp. You can view the actual output:<br>Baseline — no formatting: 130K, 1 line, 130,429 columns, 0% overhead<br>Pretty-Printed, indent=2: 285K, 11731 lines, 79 columns, 120% overhead<br>jsonfold compact=low: 167K, 2344 lines, 120 columns, 28% overhead<br>jsonfold compact=default: 167K, 2344 lines, 120 columns, 28% overhead<br>jsonfold compact=high: 166K, 2239 lines, 120 columns, 27% overhead<br>jsonfold compact=max: 156K, 1321 lines, 255 columns, 20% overhead<br>Key ideas<br>Do not replace the serializer<br>For my implementation, I chose NOT to build another serializer. There are already many good serializers available in multiple languages. Many of them support custom transformations, special handling for application classes, non-standard numeric values, date/time objects, and other data types. For example:<br>The Python json module — JSON encoder and decoder provides options for custom data types, NaN handling, custom encoders, and more.<br>JavaScript’s JSON.stringify() supports a replacer function that can alter the stringification process.<br>Java Jackson ObjectMapper can perform complex transformation of POJOs based on annotations, introspection and templates.<br>Wrap the output stream<br>Instead of replacing or extending the serializer, jsonfold acts as a filter between the serializer and the final output stream.<br>The serializer still does what it already knows how to do: convert application data into valid JSON text. jsonfold only looks at the generated pretty-printed output and decides which parts can be safely folded back onto one line.<br>This keeps all the existing serializer functionality and customization in place.<br>Operate on pretty-printed token stream<br>The jsonfold does not reparse the JSON format or reconstruct the data objects. Instead, it operates directly on the pretty-printed token stream generated by the serializer. It relies on a few assumptions:<br>The input is valid JSON.<br>Each input line represents an atomic JSON fragment that can be safely moved or merged as a unit, and should NOT be split or reformatted.<br>Indentation provides structural clues about the relationship between elements.<br>If the above assumptions are violated, the jsonfold falls back into "raw" mode - where the data is passed through unchanged, without attempting any unsafe transformation.<br>The three phases<br>The compaction is done in three logical phases, we will name them: pack , fold and join . Each one performs a...