JSON to Markdown
How to convert JSON to a Markdown table
rows.page turns JSON or JSONL files up to 1.5 GB into a Markdown table of the first 1,000 rows, free with no signup: open the file, then click Export > Markdown. It runs in your browser, and nested objects become dot-path columns such as user.name.
No file handy? Open Every country, as nested JSON (250 rows, 1.4 MB).
How to convert JSON to a Markdown table in rows.page
- Drop a
.json,.jsonl,.ndjsonor.ldjsonfile on the page, or click Paste data, paste JSON or JSONL and click Open. - Hide the columns you don't want in the Columns panel, and narrow the rows with the filter box.
- Click Export and choose Markdown.
- Paste the table into your README, pull request or docs.
DuckDB-WASM reads the file inside your browser, so nothing is uploaded unless you click Share. The grid has no row limit and loads rows in pages of 100, while the Markdown export writes the first 1,000 rows of your current view.
A .json file over 1.5 GB is refused with "Too big for this browser". A larger JSONL file loads partially, with a note saying how many rows fit.
How nested objects, arrays and nulls become Markdown cells
rows.page flattens nested objects into dot-path columns such as user.address.city, up to 8 levels deep and 200 child fields per object. A column holding JSON text is expanded too when 90% or more of its values in the first 1,000 rows are JSON objects.
If the file is one top-level wrapper such as {"data": [...]}, rows.page unwraps it to its biggest list, up to 4 levels deep, and shows the note: Showing the N items in "data"; the other top-level fields were skipped. The export then keeps the pipe table valid:
| JSON input | Markdown output |
|---|---|
{"user": {"name": "Ada"}} | A column named user.name with the value Ada |
"note": null | An empty cell |
"tags": ["a", "b"] | The cell ["a","b"], written as JSON text |
"msg": "a|b" | The cell a\|b, with the pipe escaped |
"id": 1 | The cell 1 |
For the input [{"id": 1, "user": {"name": "Ada"}, "tags": ["a", "b"], "note": null}], the export looks like this:
| id | user.name | tags | note |
| --- | --- | --- | --- |
| 1 | Ada | ["a","b"] | |Line breaks inside a value become spaces, because a newline would end the row. The delimiter row is always plain ---, so add colons yourself if you want columns aligned.
How to filter JSON rows before exporting to Markdown
Export writes your current view: the filter, sort order and visible columns. If the JSON has dozens of nested keys that would make a README table too wide, hide the extra columns first. To cut rows without SQL, type in the filter box or click histogram bars and top values in the Columns panel:
country:NLmatches a value.price:>20compares numbers.name:*keeps rows where the field has a value.-name:*keeps rows where the field is empty.
To give readers every row, click Share to upload the file and get a https://rows.page/<id> link they can filter and sort next to the 1,000-row table in your pull request.
How to pick and rename JSON fields with SQL
To keep a few fields or rename dot-path headers, type SQL into the filter box. A statement that starts with SELECT, WITH or FROM runs against the table data, and column names with dots need double quotes:
SELECT id, "user.name" AS name FROM datarows.page uses DuckDB SQL, so window functions, QUALIFY, unnest(), PIVOT inside a subquery and FROM (SUMMARIZE data) work. A hidden __rid column holds the row number: SELECT DISTINCT * EXCLUDE (__rid) FROM data removes duplicates, and ORDER BY __rid keeps the file order.
SQL results show up to 1,000,000 rows, and CSV, JSON, JSONL or Parquet exports of a result stop there. A Markdown export of a result still stops at 1,000 rows.
How to convert JSON to Markdown with Python and pandas
In a script or notebook, flatten the records with pd.json_normalize() and call .to_markdown():
import json
import pandas as pd
with open("data.json") as f:
records = json.load(f)
print(pd.json_normalize(records).to_markdown(index=False)).to_markdown() needs the tabulate package and raises an import error without it. pandas has no 1,000-row cap, but lists print as Python lists such as ['a', 'b'], a | inside a value is not escaped, and you write the code to filter rows or unwrap a top-level object like {"data": [...]}.
How to make a Markdown table from JSON with jq
jq has no Markdown formatter, so you list the fields and join them with pipes yourself:
jq -r '
["id", "user.name"],
["---", "---"],
(.[] | [.id, .user.name])
| "| " + join(" | ") + " |"
' data.jsonThis suits small, predictable files in a pipeline. join turns nulls into empty cells but fails on arrays and objects, so wrap those fields in tojson, and it does not escape a | inside a value.
rows.page limits and prices
| What | Limit or price |
|---|---|
| Open a file in your browser | Files up to 1.5 GB, $0, no account, nothing uploaded |
| Share a link without an account | $0, files up to 100 MB, link deleted 7 days after creation |
| Free account | $0, 10 datasets kept, last 3 versions |
| Pro | $12/month, 100 datasets, files up to 500 MB, private links |
| Max | $39/month, 1,000 datasets, files up to 2 GB, private links |
Questions
Does rows.page upload my JSON file when I convert it?
No. Opening a file is free, needs no account and happens inside your browser. The file is only uploaded if you click Share or push it with curl -T data.json https://rows.page.
Why does my Markdown export stop at 1,000 rows?
rows.page caps Markdown exports at the first 1,000 rows of the current view or SQL result. For more rows, export CSV, Parquet, JSON or JSONL, which write every matching row of a filtered view or up to 1,000,000 rows of a SQL result.
Can I convert JSON from a URL to a Markdown table?
Yes. Put the link after https://rows.page/, as in https://rows.page/https://example.com/data.json; if the host blocks cross-origin requests, the proxy fetches up to 100 MB within 30 seconds and stores nothing. For a file on GitHub, use the raw.githubusercontent.com link, because a github.com /blob/ page returns HTML.
Can I convert an Excel or YAML file to a Markdown table in rows.page?
No. rows.page reads CSV, TSV, JSON, JSONL and Parquet, not .xlsx, .xls, YAML, XML, PDF or SQLite. From Excel or Google Sheets, copy the cells and use Paste data; they arrive tab-separated and export to Markdown like any table.
How do I share the full JSON dataset along with my Markdown table?
Click Share or run curl -T data.json https://rows.page. One push takes up to 100 MB. Without an account you get 50 pushes and 1 GB per IP address per UTC day, and links expire after 7 days; sign in with Google to keep up to 10 datasets on the Free plan.