Available in Englishvust.ai
vust

Markdown · JSON to MD

Convert JSON to Markdown

Paste JSON — get a Markdown table for arrays of objects, or a structured list for nested objects. Choose your output style.

Free · No signup · Instant

Free, no signup. Up to 1 MB per request.

Auto-formatTables for arraysInstant

This tool handles

  • Arrays of flat objects → tables
  • Nested objects → indented lists
  • Column union for mixed keys
  • Primitive values preserved as literals

Not in scope

  • Deep nesting beyond 4 levels (inline JSON code block)
  • JSON Schema-specific conventions

Try it live with the widget above — paste and see the output instantly. For the items under “Not in scope,” the migration guide below covers workarounds and when to use a different tool.

JSON to Markdown examples

Paste real JSON in the left column, see the Markdown output on the right.

Array of flat objects → table

JSON

[{"name":"Alice","age":30},{"name":"Bob","age":25}]

Markdown

| name | age | | --- | --- | | Alice | 30 | | Bob | 25 |

Column union across objects

JSON

[{"a":1,"b":2},{"a":3,"c":4}]

Markdown

| a | b | c | | --- | --- | --- | | 1 | 2 | | | 3 | | 4 |

Nested object → list

JSON

{ "user": { "name": "Alice", "age": 30 } }

Markdown

- **user** - **name**: Alice - **age**: 30

How JSON-to-Markdown conversion works

01

Paste JSON — Paste JSON into the input field.

02

Pick format — Auto chooses table for arrays of objects and list for nested objects.

03

Copy — Copy the Markdown output.

JSON edge cases we handle

Column union

Arrays with objects having different keys merge into a union — missing fields render as empty cells.

Primitive values

Strings, numbers, booleans, and null are rendered as literals. Complex nested values become inline JSON code.

Deep nesting cap

Beyond the configured max depth (default 4) nested structures fall back to an inline JSON code block to stay readable.

Invalid JSON

Parse errors are returned as inline warnings — the tool never silently discards broken input.

What is a JSON-to-Markdown conversion?

JSON (JavaScript Object Notation) is the ubiquitous data interchange format of the modern web — it's how APIs return data, how config files are serialized, how logs are structured, and how front-ends talk to back-ends. Its structure is minimal and nested: objects (key-value pairs), arrays, strings, numbers, booleans, null. Markdown is plain-text documentation. Converting between them means deciding how JSON's nested structure maps onto Markdown's flat text primitives.

Our converter makes pragmatic choices by shape. An array of flat objects ([{...}, {...}, {...}] where each object has the same or similar keys) becomes a GFM table — one row per object, columns for the union of keys. A nested object ({user: {name: ..., age: ...}}) becomes an indented Markdown list — one bullet per key, nested content indented two spaces deeper. Deeply nested structures (beyond the configurable max depth, default 4) fall back to inline JSON code blocks rather than producing unreadable 10-level-deep lists.

The result is JSON that reads like documentation instead of source code — no raw { } braces, no trailing commas, no syntax highlighting dependency.

Why convert JSON to Markdown?

Four common drivers. First, API documentation: you have a JSON response schema — maybe the success body of a REST endpoint, maybe a webhook payload — and you want it to appear in your API reference docs. Embedding the raw JSON works but demands reader parsing; embedding as a GFM table (if the shape supports it) or as a labeled list makes the schema immediately scannable. Engineers reading API docs prefer "what does this return" as a readable reference, not as raw JSON they have to decode.

Second, config documentation: your tool has a configuration file in JSON format (or a section of a larger config that's JSON-shaped). The config file should exist as JSON — that's what your tool consumes — but the documentation for the config (what fields exist, what types, what defaults) benefits from table or list rendering. A Markdown table of config fields is easier to reference than hunting through a JSON schema.

Third, data reporting: your analytics pipeline returns a JSON list of metrics, your monitoring system dumps a JSON array of events, your LLM returns structured JSON output for a query. You want to include that in a weekly report, a retrospective, a team page, a blog post. JSON to Markdown table preserves the data while making it readable in prose contexts.

Fourth, debug and audit logs: a JSON log entry has timestamps, user IDs, event names, metadata — reviewing a handful of them in a ticket or a post-mortem benefits from tabular rendering, not from scrolling through formatted JSON.

Manual approach

Hand-converting flat JSON to a Markdown table is bearable for three rows, painful for fifteen. You count the keys, write the header row with | between each, write the separator row with |---| for each column, then for each object in the array, write one data row with the values in matching column order. Quoting and escaping get fiddly — | inside a string value breaks the table; double-quotes need to be preserved or escaped; nested values need a policy.

Nested JSON to Markdown list is easier to start but harder to make consistent. A deep tree requires disciplined indentation; two-space vs four-space indent is a coin flip you need to stay consistent with; keys in inline code vs bold is a style decision. For anything beyond a toy example, tooling pays off immediately.

For a 50-object array, hand-conversion is a half-hour of mechanical typing with several errors to fix after preview. For nested JSON with 20 levels, the manual approach is mostly copy-paste-reformat and still produces inconsistent output.

Automated approach (our tool)

Our JSON-to-Markdown engine is a purpose-built transformer written in TypeScript. It accepts either a JSON string (we parse it and surface errors as warnings) or a pre-parsed object. Depending on the shape and the mode option, it produces one of three output types:

Table mode (default for arrays of flat objects). For input like [{name: "Alice", age: 30}, {name: "Bob", age: 25}], the engine produces:

| name | age |
| --- | --- |
| Alice | 30 |
| Bob | 25 |

Column header is the union of keys across all objects. Rows with missing keys render as empty cells (table stays aligned). This is the intended output for the most common JSON-to-docs use case: turning API response arrays or config schemas into reference tables.

List mode (default for nested objects). For input like {user: {name: "Alice", age: 30}}, the engine produces:

- **user**
  - **name**: Alice
  - **age**: 30

Keys are bolded; primitive values follow on the same line; nested objects recurse with two-space indentation. This works well for deeply hierarchical configs or documents where keys have descriptive names.

Auto mode (default). The engine inspects the input and picks table vs list based on shape: arrays of objects → table; nested objects → list; mixed or primitive → list fallback.

Max depth cap. To prevent runaway nesting producing illegible output, the engine caps at 4 levels by default. Beyond that, the engine renders the over-depth subtree as an inline JSON code block — preserving content without demanding a 10-space indent that no one can read.

Column union for mixed arrays. If your array has objects with different keys (common in real-world API responses — some records have an optional email field, others don't), the table includes all keys from all objects, with empty cells where a key is missing. No data is silently dropped.

Primitive handling. Strings render as-is. Numbers and booleans render as their literal value (true, false, 42). null renders as null. Arrays of primitives (like tags: ["a", "b", "c"]) render as inline JSON code blocks — Markdown has no great inline-array primitive.

Common gotchas

Column order follows first-object key order. Our engine builds the column list by iterating the first object's keys, then appending any new keys from subsequent objects. If your API returns objects where the key order varies, the output column order follows the first object. For deterministic column order, sort your data or transform it before passing to our tool.

Deeply nested arrays become inline JSON blocks. An array of objects nested inside another object's field (e.g., {users: [{...}, {...}]}) doesn't auto-expand into a sub-table within the outer list. It renders as an inline JSON code block for the nested array. If the nested array is the actual thing you want to render, extract it: users from the outer object, pass that array directly.

Large numbers lose precision. JSON's number type is a 64-bit float, which limits integer precision to 2^53. If your JSON has integer IDs larger than that (common with database primary keys or Twitter IDs), they may arrive truncated or imprecise. This is a JSON limitation, not ours. For large-int precision, pass IDs as strings in your JSON.

Date strings stay as strings. JSON has no native date type — dates are always strings (ISO 8601 is the convention: "2026-04-24T12:34:56Z"). Our output preserves them verbatim. No automatic "pretty date" formatting. If you want readable dates, pre-process your JSON to convert ISO strings to your preferred format.

Escape characters in strings. Newlines in JSON strings ("foo\nbar") would break a Markdown table row. Our engine escapes them to <br> for safe in-cell rendering. Unicode characters, emoji, and accented characters pass through as-is.

Circular references crash. If your JSON has circular references (rare, only an issue if you hand-construct with JSON.parse then add circular links), the parser will have already failed — our engine never sees it. The input is string JSON, which is by definition non-circular.

Objects with function-named keys. If your JSON has keys like "constructor" or "__proto__", some parsers get confused. Standard JSON.parse is safe; our engine uses it. No prototype pollution risk.

When to use a different tool instead

For interactive data exploration before converting: jq or fx (command-line JSON processors) let you filter, transform, and restructure JSON before conversion. Pipe jq output into our tool when you need to extract or reshape data first.

For converting JSON Schemas (not data, but structure definitions): JSON Schema files have different conventions — $schema, properties, required. Our tool treats them as data, which produces usable but not ideal output. Dedicated JSON Schema renderers (e.g., docson, json-schema-to-markdown) exist for that use case.

For converting OpenAPI/Swagger specs: these are YAML or JSON with API-specific structure. Use dedicated tools like widdershins, Swagger UI exports, or Redocly's generators — they understand API semantics and produce better API reference output than a generic converter.

For pretty-printed JSON (not converted to Markdown): our tool always converts to table or list. If you just want syntax-highlighted JSON inline, use a Markdown code fence with json language hint instead of our tool.

For massive datasets (10,000+ records): a Markdown table with 10,000 rows is not useful — nobody reads that. Consider summarizing (aggregates, top-N) or linking to the raw data instead.

Migration workflow

A workflow for turning JSON data into Markdown documentation:

  1. Identify the JSON's shape. Array of objects? Single nested object? Array of arrays? Our tool picks output mode based on shape, but knowing ahead tells you which mode you want — and whether any reshaping is needed first.
  2. Filter and reshape if needed. Use jq (command-line) or JavaScript .map/.filter or Python's json module to extract just the data you want to document. Trimming before conversion produces cleaner output.
  3. Decide mode: table or list. For flat arrays of similar objects → table. For nested objects → list. For mixed → pick one; the other is reasonable but less natural.
  4. Paste into our tool and review. Verify that all keys are present in the output, column order makes sense, numeric values render correctly, dates are formatted consistently, and nested structures aren't overly deep.
  5. Customize by hand if needed. Reorder columns by editing the header row and matching data cells (GFM rendering honors your order). Adjust column alignment with :---: for center, ---: for right.
  6. Include a description paragraph. A Markdown table or list by itself is often cryptic. Add a one-to-two-sentence description above it: "Response payload from GET /users", "Supported configuration options", "Weekly metric snapshot as of 2026-04-24."
  7. Link to source. If the JSON came from an API, link to the endpoint documentation. If it came from a config file, link to the file in your repo. Readers often want to regenerate or verify.
  8. Preview in target platform. GitHub renders GFM tables cleanly. Notion, Confluence, Obsidian each have quirks — test once to see how your output looks there before committing to a format.

For API reference documentation (the most common use case), expect 3-5 minutes per endpoint's JSON sample — fast once you have a rhythm. For one-off reports with a single JSON source, under a minute.

Frequently asked questions

Process bigger files in @vustMarkdownBot

500-character free conversions in chat — pay-as-you-go for longer text.

Open Telegram bot
    JSON to Markdown Converter — VUST