JSON to Markdown
Free online JSON to Markdown tool. Convert JSON array or nested object into GitHub README / tech doc / blog ready GFM Markdown table in one click. Supports 4 nest modes (Flatten / First key / Stringify / Raw JSON), depth 1-6, custom separator, key beautification (user_name → User Name), column sort, smart multi-table split (auto-detect top-level arrays), null placeholder, 3 alignments, 9 options real-time preview, fully local browser execution.
Related
About JSON to Markdown and Markdown Tables
JSON to Markdown tool (JSON to Markdown Converter) automatically converts JSON data structures into standard GFM (GitHub Flavored Markdown) table code. It frees developers from manually writing `|` / `-` table separators, especially for converting API responses, config files, or any JSON structure into tech docs, README, and blogs.
Markdown table is a plain text table representation proposed by John Gruber in 2004 in Markdown syntax, using `|` to separate cells, `-` to define header separator row, optional `:` to control alignment. GFM (GitHub Flavored Markdown) extends standard Markdown with table syntax, natively supported by GitHub, GitLab, Bitbucket, Notion, Confluence, Slack, Discord, VS Code, and most modern platforms. Tool output strictly follows GFM spec.
Three types of JSON to Markdown tools on the market: ① only generate Markdown code string (jsonformatter.org, convertcsv.com), emphasize 'copy and use'; ② provide advanced config (depth flatten / key beautify / multi-table split), represented by this tool; ③ support reverse Markdown → JSON parsing, inverse operation of this tool.
Tool's 'nested flatten + key beautify' is the differentiating highlight: traditional tools display {user:{name:'Alice'}} as `{"name":"Alice"}` string directly, this tool recursively expands to `user.name` column (max 6 depth, separator configurable), and transforms `user_name` / `userProfileId` to `User Name` / `User Profile Id` Title Case headers, making headers more human-readable. This means you can directly process nested structures of GitHub API, Stripe API, Notion API without pre-flattening with jq / lodash.
Another highlight is 'smart multi-table split': when JSON has multiple top-level array fields (e.g. {users:[...], orders:[...], products:[...]}), tool auto detects and splits each array into independent Markdown table, each with auto-generated `### name` H3 caption, making long documents clearly navigable.
Markdown table vs HTML table's biggest advantage is 'plain text version control': `.md` files with git diff can clearly see table row additions/removals, while HTML table's `<tr>` `<td>` in diff tools often display as long hard-to-read lines. This is why GitHub, GitLab and other code hosting platforms make Markdown table the default data display method.
Use Cases
- Tech docs: convert API response JSON into Markdown table for display
- GitHub README: show config data, parameter description, API response examples
- Data reports: present analysis results in Markdown table (export to Notion / Confluence)
- API docs (Swagger / Redoc / OpenAPI): clearly display interface response data structure
- VuePress / Docusaurus / Hexo static site generators' doc chapters
- Slack / Discord / enterprise IM: share structured data (GFM natively supported)
- VS Code / JetBrains IDE Markdown Preview real-time table effect preview
- Version control collaboration: Markdown table is plain text, git diff friendly, easy Code Review
- Teaching: convert students' nested JSON assignments into tables for unified review
- Email templates (Markdown-supporting email clients like Bear Mail, HEY)
- Notion database import: generate Markdown table first, then paste into Notion
- Internationalization: JSON flatten + key beautify, share same structure across language docs
How to Use
- Paste JSON array (recommended) or nested object into left editor, or click 'Sample' to load 3 nested user examples, or click 'Upload' to upload .json / .txt file
- Choose nest mode in toolbar (recommended 'Flatten'), if JSON has multi-level nesting increase Max Depth
- To customize separator, fill in Separator input (default `.`, can be `_` / `-` / `/`)
- Choose Strategy: single array pick 'Single'; multi-array field pick 'Multi' for auto split; force split pick 'Split'
- Toggle style options: Sort columns / Beautify keys / Exclude empty / Include Caption / Include Index
- Choose alignment: left / center / right
- Click 'Convert' button (or press Enter) to trigger conversion; input has 500ms debounce
- Right side shows generated Markdown table code, after satisfaction click 'Copy' to copy to Markdown doc, or 'Download' to save as table.md
Features
- Nested auto flatten: recursively expand {user:{name,age}} into dot-notation keys (depth 1-6) — no hand-written flatten script needed
- 4 nest modes: Flatten (recommended, depth adjustable) / First key (nested as single JSON column) / Stringify (nested → JSON string) / Raw JSON (each row = one JSON block)
- Smart multi-table split: detect top-level array fields (e.g. users, orders), auto split into multiple Markdown tables each with a ### caption
- Custom separator: flatten mode default `.` (Lodash / MongoDB convention), customizable to `_` / `-` / `/`
- Key beautification (camelCase / snake_case → Title Case): `user_name` → `User Name`, `userProfileId` → `User Profile Id`
- Column sort: one click to sort all headers alphabetically, for stable column order across documents
- Empty column exclusion: auto-detect columns where all rows are null / undefined / empty string, exclude them
- 3 alignment styles: left (`:-`) / center (`:-:`) / right (`-:`), per GFM spec
- Row index toggle: optional # numbered column on the leftmost position with custom header text
- Caption toggle: auto generate `### name` H3 heading above each table for clear document navigation & SEO
- Type-aware escape: `|` / `\` / newline auto escaped to `\|` / `\\` / `<br>`, no broken Markdown tables
- Generation stats feedback: footer shows 'N tables × M rows × K cols' + bytes for long JSON debugging
- Sample data + file upload: built-in 3 nested user examples, support drag-drop or click to upload .json / .txt
- Fully local browser execution: all parsing / flattening / Markdown generation / copy / download happens in your browser, no data sent to any server
Code Examples
JavaScript: fetch + Nested Flatten + Markdown Output
javascriptMost common usage: call GitHub API, flatten nested objects into dot-notation keys, generate Markdown table via this tool.
async function fetchUsers() {
const res = await fetch('https://api.github.com/users?per_page=10');
return await res.json();
}
function flattenObject(obj, prefix = '', sep = '.', result = {}, depth = 0, maxDepth = 3) {
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return result;
if (depth >= maxDepth) {
if (prefix) result[prefix] = JSON.stringify(obj);
return result;
}
for (const [k, v] of Object.entries(obj)) {
const key = prefix ? `${prefix}${sep}${k}` : k;
if (v && typeof v === 'object' && !Array.isArray(v)) {
flattenObject(v, key, sep, result, depth + 1, maxDepth);
} else {
result[key] = v;
}
}
return result;
}
function generateMarkdownTable(rows, opts = {}) {
const { align = 'left', includeIndex = false, sortColumns = false } = opts;
const flat = rows.map(r => flattenObject(r));
let cols = [...new Set(flat.flatMap(r => Object.keys(r)))];
if (sortColumns) cols.sort((a, b) => a.localeCompare(b));
const alignMap = { left: ':-', center: ':-:', right: '-:' };
const alignSep = alignMap[align];
const headers = includeIndex ? ['#', ...cols] : cols;
const seps = includeIndex ? [alignSep, ...cols.map(() => alignSep)] : cols.map(() => alignSep);
const escapeCell = v =>
v == null ? '' :
typeof v === 'object' ? JSON.stringify(v).slice(0, 60) :
String(v).replace(/\\|/g, '\\|').replace(/\n/g, '<br>');
const lines = [];
lines.push('| ' + headers.join(' | ') + ' |');
lines.push('| ' + seps.join(' | ') + ' |');
flat.forEach((r, i) => {
const idxCell = includeIndex ? [i + 1] : [];
const cells = cols.map(c => escapeCell(r[c]));
lines.push('| ' + [...idxCell, ...cells].join(' | ') + ' |');
});
return lines.join('\n');
}
const users = await fetchUsers();
const md = generateMarkdownTable(users, { align: 'left', sortColumns: true });
console.log('## GitHub Users\n\n' + md);Python: Flask Backend Generates Markdown Report
pythonBackend aggregates multi-source data, generates Markdown table with Python (no frontend dependency), suitable for CI/CD auto weekly report.
import json
def flatten(obj, prefix='', sep='.', result=None, depth=0, max_depth=3):
if result is None:
result = {}
if not isinstance(obj, dict) or depth >= max_depth:
if prefix:
result[prefix] = json.dumps(obj) if isinstance(obj, (dict, list)) else obj
return result
for k, v in obj.items():
key = f"{prefix}{sep}{k}" if prefix else k
if isinstance(v, dict):
flatten(v, key, sep, result, depth + 1, max_depth)
else:
result[key] = v
return result
def json_to_markdown_table(data, align='left', include_index=False,
sort_columns=False, caption=None):
if isinstance(data, dict):
data = [data]
if not data:
return "<!-- No valid objects found -->"
flat_rows = [flatten(row) for row in data]
columns = []
for row in flat_rows:
for k in row:
if k not in columns:
columns.append(k)
if sort_columns:
columns.sort()
align_sep = {'left': ':-', 'center': ':-:', 'right': '-:'}[align]
headers = (['#'] if include_index else []) + columns
seps = ([align_sep] if include_index else []) + [align_sep] * len(columns)
def escape_cell(v):
if v is None:
return ''
if isinstance(v, (dict, list)):
s = json.dumps(v)
return s[:60] + '…' if len(s) > 60 else s
return str(v).replace('|', '\\|').replace('\n', '<br>')
lines = []
if caption:
lines.append(f'### {caption}\n')
lines.append('| ' + ' | '.join(headers) + ' |')
lines.append('| ' + ' | '.join(seps) + ' |')
for i, row in enumerate(flat_rows):
idx_cell = [str(i + 1)] if include_index else []
cells = [escape_cell(row.get(c, '')) for c in columns]
lines.append('| ' + ' | '.join(idx_cell + cells) + ' |')
return '\n'.join(lines)
if __name__ == '__main__':
data = json.load(open('weekly_stats.json'))
md = json_to_markdown_table(data['users'], align='left', sort_columns=True, caption='Weekly Active Users')
print(md)Command Line: jq Aggregate + This Tool for GitHub Release Notes
bashOps scenario: pull PR list from GitHub API, aggregate and flatten with jq, paste into this tool to generate GFM Release Notes.
# 1) Use gh CLI to pull latest 50 merged PRs
PR_JSON=$(gh pr list --state merged --limit 50 --json number,title,author,labels,mergedAt)
# 2) Flatten labels nested array with jq
echo "$PR_JSON" | jq 'map({
number: .number,
title: .title,
author: .author.login,
labels: (.labels | map(.name) | join(", ")),
mergedAt: .mergedAt
})' > release_prs.json
# 3) Open this tool, paste release_prs.json content
# - Toolbar Strategy pick 'Single'
# - Check Sort columns + Include Index
# - Click Convert
# - Copy generated Markdown table
# 4) Splice into Release Notes
cat > RELEASE.md <<'EOF'
# v2.1.0 Release Notes
## What's Changed
EOF
sed -i '/## What/ r /tmp/table.md' RELEASE.md
cat >> RELEASE.md <<'EOF'
Full Changelog: https://github.com/your/repo/compare/v2.0.0...v2.1.0
EOF
# 5) Use gh CLI to create Release
gh release create v2.1.0 -F RELEASE.md -t "v2.1.0"FAQ
How to convert JSON data to Markdown table?
Paste a JSON array (each element an object) or a single object into the left input, click toolbar 'Convert' button, the right panel shows GFM-standard Markdown table code. Copy and paste directly into GitHub README, Markdown blog, Confluence, Notion docs.
Can nested JSON objects be converted to Markdown table?
Yes. 4 nest modes are built in: ① Flatten (recommended): recursively expand {user:{name:'Alice',age:30}} into user.name / user.age columns, depth 1-6 adjustable; ② First key: only take top-level fields, nested object as JSON string; ③ Stringify: nested objects unified to JSON string; ④ Raw JSON: each row is a complete JSON block (for code snippet display).
Can the separator for flattened keys be changed?
Default `.` separator (`user.name`), matching JavaScript / MongoDB / Lodash convention. For `user_name` (snake_case) or `user/name` (path style), customize in toolbar's 'Separator' input (max 3 chars).
What does 'Beautify keys' do?
After enabling, `user_name` / `userProfileId` keys are auto converted to `User Name` / `User Profile Id` Title Case. Implementation: convert _ / - to space, insert space before camelCase uppercase letters, capitalize first letter. This makes headers more readable for human eyes, especially for long README / API doc.
How to split into multiple tables?
Toolbar 'Strategy' dropdown has 3 options: ① Single (default): whole JSON becomes one table (for pure array); ② Multi: when JSON contains multiple array fields, auto split each array into a separate table with ### caption (for {users:[...], orders:[...]} scenario); ③ Split: forced split mode, only process array fields, ignore others.
Can the generated Markdown table be used directly in GitHub?
Yes. The generated Markdown table follows CommonMark and GFM (GitHub Flavored Markdown) spec, can be used directly in GitHub README, GitLab docs, Notion, VuePress / Docusaurus / Hexo blogs, Slack / Discord messages, VS Code Markdown Preview, and any GFM-supporting platform.
Support batch generation of multiple Markdown tables?
Yes. Switch Strategy to 'Multi' or 'Split', tool smartly detects JSON top-level array fields (users / products / orders), each array auto becomes an independent Markdown table with ### caption, for organizing long documents.
How to control header order?
By default headers follow the order in which keys first appear in JSON objects. For alphabetical order (stable column order across documents), enable toolbar 'Sort columns' switch. For fully custom order, use 'Column order' advanced feature (coming soon).
Too many empty columns, what to do?
Enable toolbar 'Exclude empty' switch, the tool auto detects columns where all rows are null / undefined / empty string and excludes them. Especially useful for sparse data (e.g. only some users filled a field), drastically reduces table width.
Will the | character in cells break the table?
No. Tool auto escapes `|` (→ `\|`), `\` (→ `\\`), newline (→ `<br>`) in cells, ensuring generated Markdown table doesn't break in any renderer. Key upgrade over competitors — most don't do escape, leading to table breaking when copying data containing `|`.
What's the difference between Markdown and HTML tables?
Markdown table is plain text format (`|` `-` syntax), suitable for tech docs / README / blog / version control collaboration, simple and readable; HTML table is web format (`<table>` `<tr>` tags), suitable for pages needing CSS / responsive layout / ARIA accessibility. Both come from same JSON, but different scenarios: use this tool for Markdown in tech docs, use JSON to HTML tool for HTML in web pages.
Maximum row count for Markdown table?
No row limit by default (unlike HTML table tool), since Markdown table is plain text with low browser rendering pressure. Recommendation: ① split into multi-table or pagination when exceeding 1000 rows; ② single GitHub README file not exceed 1MB; ③ follow platform limits when embedding in Notion / Confluence.
How to customize Caption title?
Under 'Multi / Split' strategy, each table's Caption auto uses top-level array field name (e.g. `### users`, `### orders`). Under 'Single' strategy, enable 'Include Caption' and input custom title text. Caption is `### H3` heading, conforms to Markdown document structure spec.
Is data uploaded to server? Privacy?
Fully local browser execution. All JSON parsing, nested flattening, Markdown generation, copy / download happens in your browser via JavaScript, file reading only in local FileReader, nothing sent to any server. Even sensitive API responses / internal business fields can be safely used, data cleared when page closes.
Troubleshooting
Prompt 'Please input JSON data' or similar error
Left input box is empty or only whitespace. Make sure to paste valid JSON content, or click 'Sample' to load example data, or click 'Upload' to select .json / .txt file.
Prompt 'Unexpected token ... in JSON at position N'
JSON format is invalid. Common reasons: ① trailing comma (e.g. [{},{},]); ② single quotes instead of double quotes; ③ JS object syntax (e.g. {key: value}) instead of JSON ({"key": "value"}). Use JSON formatter tool to validate and fix.
Generated table only has header no data rows
JSON data is empty array [] or empty object {}. Tool returns '<!-- No valid objects found -->' comment for empty array. Add at least one object data in source JSON.
Flatten mode column names too long (e.g. user.profile.address.city.country.code)
For deep nesting: ① switch to 'First Key' mode (only take top fields, nested as single JSON column); ② reduce Max Depth (from 6 to 3-4); ③ modify source JSON structure to reduce unnecessary nesting; ④ use toolbar's Reset button to restore default flatten config.
Multi-table split mode didn't generate multiple tables
Confirm source JSON is object structure (not pure array), and at least one field is 'array of objects' (e.g. "users": [{...}, {...}]). If top-level fields are all strings / numbers / nested objects themselves, 'Multi' strategy falls back to 'Single' single-table mode.
After Beautify Keys, header is empty
Beautify Keys feature converts snake_case to Title Case, but won't change keys that originally start with uppercase / special chars (e.g. __proto__, constructor). These are JavaScript reserved words, recommend renaming in source JSON first.
Generated Markdown renders empty in GitHub
Very rare. Common reasons: ① unescaped `|` in table (tool auto escapes, but manual modification may break); ② HTML tags in cells (GitHub doesn't render by default, tool auto converts \n to <br>); ③ file encoding not UTF-8.
Downloaded table.md opens blank in editor
Downloaded file only contains Markdown table code (starting with `|` `-` chars), no complete Markdown doc skeleton (like # title, ## chapter). Designed as snippet for embedding into existing Markdown docs. Manually add # title at file start, or directly paste into existing .md file at the position.
Chinese header shows garbled chars
Source JSON keys contain Chinese, ensure source file is UTF-8 encoded. If JSON copied from Excel may be converted to GBK, use encoding converter to UTF-8 first then paste.
Want to batch modify generated table (e.g. replace company Logo / change color)
After generation, copy Markdown table from right side, use sed / custom script to batch replace style attributes. Markdown table itself doesn't support color (unlike HTML), for colors use JSON to HTML tool (generates <table> with inline style).
After exclude empty table got wider instead
Exclude Empty excludes columns where 'all rows are null/undefined/empty string'. If a column has only 1 row with value, others empty, it won't be excluded (this is correct behavior). To exclude sparse columns, clean in source JSON first.
History lost
History is stored in browser localStorage, clearing browser data / switching to incognito / using other browser will cause history loss. Tool doesn't upload history to any server, so can't sync across devices.
Glossary
- Markdown Table
- Plain text table composed of | and - characters, defined by GFM (GitHub Flavored Markdown) spec. Tool output strictly follows this syntax, can be directly rendered by GitHub / GitLab / Notion / Confluence.
- GFM
- GitHub Flavored Markdown abbreviation, GitHub's extension dialect over standard Markdown, including tables, strikethrough, task lists, autolinks, etc. Tool's generated table conforms to GFM spec.
- CommonMark
- Markdown syntax standardization spec (released 2014). GFM table syntax extends over CommonMark. Tool's output can be correctly rendered by both strict CommonMark parsers and GFM parsers.
- JSON Array
- Object collection wrapped in square brackets [...]. Tool uses each array element as a table row; empty array generates no table (shows hint).
- JSON Object
- Key-value pair collection wrapped in curly braces {}. Tool uses each object key as table header, value as cell; single object auto wrapped as single-row table.
- Flatten
- Recursively expand nested object into dot-separated flat key name, e.g. {user:{name:'A'}} → 'user.name'. Tool supports 1-6 depth auto flatten, separator configurable.
- Beautify Keys
- Transform rule converting snake_case or camelCase keys to Title Case: user_name → User Name, userProfileId → User Profile Id. One of tool's differentiating capabilities.
- Multi-Table Split
- Detect JSON top-level array fields (e.g. users, orders), auto split into multiple independent Markdown tables. One of tool's differentiating capabilities, each split table auto generates ### caption.
- Alignment Syntax
- GFM table header separator row supports : character for alignment: :- left, :-: center, -: right. Tool provides 3 buttons for one-click switch.
- Index Column
- # numbered column on leftmost of table (from 1 incrementing), header text customizable. Tool disabled by default, when enabled convenient for referencing row numbers in docs.
- Caption
- H3 heading (###) in Markdown, tool auto adds this label above each generated table (default uses top-level array field name or user custom text), helpful for both doc navigation and SEO.
- Sort Columns
- Switch to arrange all table columns in alphabetical order. When enabled, column order stays consistent when comparing multiple documents, diff tools see changes more clearly.
- Exclude Empty
- Auto exclude column when all rows of that column are null / undefined / empty string. Tool disabled by default, when enabled drastically reduces sparse data table width.
- Markdown Escape
- Escape special-meaning characters in Markdown table (e.g. |, \, newline) to safe form (\|, \\, <br>), to avoid breaking table syntax. Tool auto does this escape, key upgrade over competitors.
- localStorage History
- Browser-provided local key-value storage (capacity ~5-10MB). Tool uses localStorage to persist recent inputs, can quickly recover after refresh or accidental close.
- Debounce
- Frontend performance optimization technique: merge high-frequency events (e.g. input) callbacks to execute once after last trigger. Tool sets 500ms debounce, avoids large file parsing lag.
4 Nest Object Processing Modes Comparison
Toolbar provides 4 modes for different nested scenarios, recommended to choose based on JSON structure complexity:
| Mode | Behavior | Sample Column | Scenario |
|---|---|---|---|
Flatten | Recursively expand nested objects into dot-separated keys (depth 1-6) | user.name / profile.role | GitHub / Stripe / Notion real API nested structures |
First Key | Only take object first-level key, nested as single JSON column | user / tags | Unfixed or too deep nesting (>6 levels); only care about top fields |
Stringify | All values forced as string, nested objects JSON.stringify + escape | \ | user (as JSON) | Debug: keep original JSON structure for visual inspection |
Raw JSON | Serialize whole row to a value column, cell is formatted JSON block | value (entire JSON) | Code snippet display, log aggregation, keep raw JSON form |
3 Table Generation Strategies Comparison
Toolbar's Strategy dropdown controls how to handle JSON with multiple array fields:
| Strategy | Suitable Input | Output Form | When to Use |
|---|---|---|---|
Single | JSON array or single object | 1 table, no caption (H3) | Pure array scenario (most common) |
Multi | Object with multiple array fields (e.g. {users:[...], orders:[...]}) | Each array → 1 table + ### caption | Multi-business aggregation (e.g. frontend dashboard data) |
Split | Any object | Force extract all top-level array fields, ignore non-array | Clearly only want array parts |
Toolbar 14 Configurable Options Reference
All 14 toolbar configurable options and their effects, for quick combo selection:
| Option | Type | Effect |
|---|---|---|
nestMode | select | Nest handling: Flatten / First Key / Stringify / Raw JSON |
maxDepth | select | Flatten mode max depth (1-6) |
separator | text | Flatten mode key separator (default ., max 3 chars) |
strategy | select | Table gen strategy: Single / Multi / Split |
align | button | Alignment: left / center / right |
includeIndex | checkbox | Add # numbered column on leftmost |
indexHeader | text | Index column header text (default #) |
sortColumns | checkbox | Sort all columns alphabetically |
beautifyKeys | checkbox | Convert keys snake/camelCase → Title Case |
excludeEmpty | checkbox | Exclude columns where all rows are empty |
includeCaption | checkbox | Add ### caption above each table |
caption | text | Custom caption text (effective under Single strategy) |
indent | select | Raw JSON mode indent (0/2/4) |
Privacy & Security
This JSON to Markdown tool's all JSON parsing, nested flattening, Markdown generation, copy / download operations completely happen in your browser locally via JavaScript. Input JSON data and generated Markdown code are not uploaded to any server, nor recorded, cached, or stored to cloud. Sensitive API responses / internal business field JSON can be safely used, closing page clears all data.
Authoritative References
- JSON Compress
- CSV to JSON
- JSON to CSV
- JSON Diff
- JSON Escape / Unescape
- JSON Flatten
- JSON Formatter
- JSON Generator
- JSONPath Query
- JSON Merge
- JSON Repair
- JSON Schema Validator
- JSON Sort
- JSON Stringify
- JSON to HTML Table
- JSON to Java
- JSON to Markdown
- JSON to SQL
- JSON to TOML
- JSON to TypeScript
- XML to JSON
- JSON to XML
- YAML to JSON
- JSON to YAML
- JSON to Python
- JSON to Go
- JSON to Rust
- JSON to Swift
- JSON to C#
- JSON to C++
- JSON to PHP