Skip to main content

jsonfold

Compact and readable JSON formatting for humans.

jsonfold makes pretty-printed JSON more compact without turning it back into unreadable one-line JSON.

Most JSON serializers offer two extremes:

  • compact machine output:
{"meta":{"version":1,"ok":true},"ids":[1,2,3,4],"matrix":[[1,2],[3,4]]}
  • fully expanded pretty-printing for humans
{
  "meta": {
    "version": 1,
    "ok": true
  },
  "ids": [
    1,
    2,
    3,
    4
  ],
  "matrix": [
    [
      1,
      2
    ],
    [
      3,
      4
    ]
  ]
}

jsonfold sits in the middle. It keeps the readable structure of pretty JSON, but selectively folds small containers and packs short scalar runs when they fit within a target line width.

{
  "meta": { "version": 1, "ok": true },
  "ids": [ 1, 2, 3, 4 ],
  "matrix": [ [ 1, 2 ], [ 3, 4 ] ]
}

This repository contains the Python implementation of jsonfold.

If you want the background story, design goals, implementation details, and examples, start with the article:

📖 Article

A Streaming JSON Formatter That Works With Existing Serializers

The article explains:

  • why existing pretty-printing often becomes unreadable,
  • the folding/packing approach,
  • streaming constraints,
  • bounded buffering,
  • and how the formatter works internally.

Features

  • Streaming filter around existing JSON serializers
  • Width-aware packing and folding
  • Bounded buffering
  • No full JSON tree reparsing
  • Human-readable output for large nested documents
  • Configurable compaction levels
  • Multiple built-in presets
  • Works with standard json.dump(..., indent=2) output

Installation

pip install jsonfold

Or from source:

git clone https://github.com/yairlenga/jsonfold
cd jsonfold
pip install .

Basic Usage

from jsonfold import dumps

obj = {
    "meta": {"version": 1, "ok": True},
    "ids": [1, 2, 3, 4],
    "matrix": [[1, 2], [3, 4]],
}

print(dumps(obj))

Output:

{
  "meta": { "version": 1, "ok": true },
  "ids": [ 1, 2, 3, 4 ],
  "matrix": [ [1, 2], [3, 4] ]
}

Streaming usage:

import json
from jsonfold import JSONFoldWriter

with open("out.json", "w") as fp:
    writer = JSONFoldWriter(fp)
    json.dump(obj, writer, indent=2)

Configuration Presets

default

Balanced default settings.

compact="default"

Typical behavior:

  • fold small objects/lists,
  • allow limited nested folding,
  • preserve readability.

low

Conservative compaction.

compact="low"

Disables nested folding/joining.


med

Moderate compaction.

compact="med"

Allows folding while restricting nested joins.


high

More aggressive packing and folding.

compact="high"

Allows:

  • larger packed scalar groups,
  • deeper nesting,
  • more aggressive joining.

max

Maximum compaction subject only to width limits.

compact="max"

Useful for very dense but still readable output.


CLI Usage

Read JSON from stdin

By default, jsonfold will read single JSON object from standard input (file or a pipe) using json.load(), and serialize it using the json.dump(..., indent=2)

python -m jsonfold < input.json
jq ... | python -m jsonfold

Use a preset:

There are few preset values - see the section above.

python -m jsonfold --compact=max < input.json

Control width:

When the output is terminal, the default width is the current terminal width. Otherwise, it will use the preset width (80 for most preset, 120 for high). The --width can override the default.

python -m jsonfold --width=100 < input.json

Read from file:

python -m jsonfold --input data.json

Use standard 'demo' document

python -m jsonfold --compact=high --demo

Sort keys:

Passed as-is to default serializer:

python -m jsonfold --sort-keys < input.json

Verbose/debug output:

To help with debugging, the verbose mode can be used. It will print all the configuration parameters that will be used before the formatting, and after the formatting it will provide statistics from the processing. Both output go to sys.stderr.

python -m jsonfold --verbose < input.json

Repository/development usage:

jsonfold is a single file module. You can run it directly in development by specifying the full path name of the py file.

python jsonfold.py < input.json

Algorithm Overview

The formatter operates directly on the pretty-printed line stream generated by:

json.dump(..., indent=2)

It does not implement a full JSON parser.

Instead, it tracks container frames and applies three phases.


Phase 1: Pack

Join consecutive scalar items onto the same line.

Example:

{
  "obj:" {
    "version": 1,
    "ok": true
  },
  "list": [
    1,
    2,
    3,
    4
  ]
}

becomes:

{
  "obj:" {
    "version": 1, "ok": true
  },
  "list": [
    1, 2, 3, 4
  ]
}

Subject to width and item limits.


Phase 2: Fold

Collapse single-content-line containers.

Example:

{
  "obj:" {
    "version": 1, "ok": true
  },
  "list": [
    1, 2, 3, 4
  ]
}

becomes:

{
  "obj:" { "version": 1, "ok": true },
  "list": [ 1, 2, 3, 4 ]
}

Phase 3: Join

Merge folded containers together.

Example:

[
  [1, 2],
  [3, 4]
]

becomes:

[ [1, 2], [3, 4] ]

Performance Notes

jsonfold is designed primarily for readability and streaming behavior.

The implementation:

  • avoids reparsing full JSON trees,
  • buffers only currently open frames,
  • streams output once folding is no longer possible,
  • and can operate incrementally on large documents.

The repository includes benchmark scripts comparing:

  • json.dumps
  • json.dump
  • folded vs unfolded modes
  • streaming vs string-building approaches

License

MIT License

Metadata

Release files for jsonfold 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jsonfold 0.2.0
File Size Uploaded Provenance
jsonfold-0.2.0.tar.gz 14.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for jsonfold 0.2.0
File Interpreter ABI Platform
jsonfold-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.1 kB

Release files / jsonfold-0.2.0.tar.gz

Download URL jsonfold-0.2.0.tar.gz
Size 14.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5a8c970c5f900c2dcce0a4613cf92d276e32f99b1813311ed76953b190eac317
BLAKE2b-256 checksum
How to use checksums
8fffb112edd8bf174b769f75f33cf810bcc5e983ab6511ff069be8681fc24968
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / jsonfold-0.2.0-py3-none-any.whl

Download URL jsonfold-0.2.0-py3-none-any.whl
Size 16.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc6bf5dc9fa894724f3087766472781b6f31200e764e4a746e251474a1fa8787
BLAKE2b-256 checksum
How to use checksums
d52b749544c0d6c46a8afaea6a71ef74a9e77bde62feccba8f80a5a7be85bbe1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for jsonfold 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page