Example
[{"name": "Ana", "role": "admin"}, {"name": "Ben", "email": "ben@example.com"}]
<table>
<thead>
<tr><th>name</th><th>role</th><th>email</th></tr>
</thead>
<tbody>
<tr><td>Ana</td><td>admin</td><td></td></tr>
<tr><td>Ben</td><td></td><td>ben@example.com</td></tr>
</tbody>
</table>
The second object has no role and the first has no email; both still get a cell in every column.
Rendering JSON as a table in code
const esc = (s) => String(s ?? '').replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' })[c]);
function toTable(rows) {
const keys = [...new Set(rows.flatMap(Object.keys))];
const head = keys.map((k) => `<th>${esc(k)}</th>`).join('');
const body = rows.map((r) => `<tr>${keys.map((k) => `<td>${esc(r[k])}</td>`).join('')}</tr>`).join('');
return `<table><thead><tr>${head}</tr></thead><tbody>${body}</tbody></table>`;
}
import pandas as pd
pd.DataFrame(records).to_html(index=False, na_rep="")
pd.json_normalize(records).to_html(index=False) # flattens nested fields
Prefer a spreadsheet? Use JSON to CSV. Exploring deeply nested data? The JSON viewer shows it as a collapsible tree.
Frequently asked questions
How are the columns chosen?
For an array of objects, every key that appears in any object becomes a column, in the order the keys first appear. A row that lacks a key gets an empty cell, so records with different fields still line up. A single object becomes a two-column key/value table, and an array of plain values a one-column list.
What happens to nested objects and arrays?
By default they become nested tables inside the cell, so you can see the whole structure. Untick “Nested tables for objects” to show them as compact JSON instead, which keeps the table flat and is easier to paste into an email or a document.
Is the HTML safe to put on a page?
Yes. Every key and value is HTML-escaped, so a value like <script> or "><img onerror=…> is shown as text and never runs. The table has no inline styles or classes, so it takes on the styles of the page or email you paste it into.
Can I get a spreadsheet instead?
Use JSON to CSV, which flattens nested fields into dotted column names; the CSV opens in Excel, Numbers and Google Sheets. To just look at JSON data as a table without making HTML, the CSV viewer and JSON viewer are quicker.