Convert one JSON document into deterministic, human-readable GitHub Flavored Markdown.
Runs in the browser, in Node, in Go, and on the command line.
Output is a readable projection rather than a reversible serialization format. Every document begins with a # Results heading (replace or omit it via the heading option), leaves values bare unless showTypes: true opts into type annotations — 42 *(integer)* — and uses canonical spacing: LF endings, one blank line between blocks, no trailing spaces, one final newline.
Motivation
If you feed JSON into an LLM, you pay for its punctuation. Every {, }, ",
:, and , is tokens spent on structure the model does not need to read the
data. Converting the same document to Markdown headings and lists is measurably
cheaper and easier for models to follow:
-
Fewer tokens. A tiktoken measurement] of one real document
came out to 13,869 tokens as JSON versus 11,612 as Markdown — about 16% less.
Reports in the wild put the JSON tax anywhere from [15–20%][md-reddit] up to 2x
depending on how nested and quote-heavy the data is. -
Native format. Markdown is the lingua franca of LLM training corpora, so
it tends to tokenize efficiently and models parse its structure reliably. -
Human-readable in the loop. Prompts, agent memory logs, and RAG context
are easier to read, diff, and hand-edit as Markdown than as escaped JSON — and
Markdown chunks concatenate cleanly, where stringified JSON does not. -
Fits tighter context windows. In IDE assistants and agent loops where
context is aggressively trimmed, token-heavy JSON is a real risk; a leaner
projection leaves more room for the actual task.

rajnandan1
/
json-to-md
JSON to Markdown conversion that runs byte-identical in the browser, Node, Go, and CLI
json-to-md
Convert one JSON document into deterministic, human-readable GitHub Flavored Markdown.
The same conversion runs in the browser, in Node, in Go, and on the command line. The TypeScript and Go implementations produce byte-identical output, enforced by a shared corpus/ and a cross-implementation fuzz gate in CI. Output is a readable projection rather than a reversible serialization format. Every document begins with a # Results heading (replace or omit it via the heading option), leaves values bare unless showTypes: true opts into type annotations — 42 *(integer)* — and uses canonical spacing: LF endings, one blank line between blocks, no trailing spaces, one final newline.
Motivation
If you feed JSON into an LLM, you pay for its punctuation. Every {, }, "
:, and , is tokens spent on structure the model does not need to read the
data. Converting the same document to…