JSON to HTML Table Converter turns one JSON object or an array of objects into a semantic table with a thead, a single header row, and a tbody of data rows, all escaped for HTML text context and rendered locally in your browser. The converter is a deterministic, copy-ready alternative to writing JavaScript loops that call document.createElement and assign textContent by hand, especially when you need the output for documentation, a static page, an email draft, or a developer handoff rather than a live runtime table. Because everything runs in the current tab, the tool does not upload your data, evaluate your input as JavaScript, call an API, or inject the generated markup with innerHTML. That removes two common failure modes of hand-rolled JSON-to-table code: prototype-pollution mistakes that come from treating JSON keys as live property names, and XSS exposure that comes from concatenating values into raw HTML. The fragment is intentionally minimal — no CSS classes, no inline styles, no caption, no IDs, and no inferred data attributes — so the consuming page owns its own styling and accessibility context.

Before you paste anything, validate the JSON shape with JSON Validator so you can see exactly which line and column would otherwise be rejected as a parse error. The two tools share the same strict RFC 8259 expectations, and the validator gives you a structure diagnostic before you commit to a conversion.

convert json to html table javascript
Convert JSON to HTML Table in JavaScript Safely

Input shapes the converter accepts and rejects

The converter is strict on purpose. Comments, trailing commas, undefined, NaN, Infinity, BigInt literals, and JavaScript object literal syntax are all rejected, because they are not valid JSON and accepting them would create two divergent interpretations of the same input. The root value also matters: the table needs named columns, and a primitive root cannot supply them in a stable way.

Input shapeAccepted?What the converter produces
One JSON objectYesA single header row and one body row
Non-empty array of objectsYesA header row plus one body row per array member
Empty arrayNoRejected: no records means no columns
Array containing primitivesNoRejected: every member must be an object
Primitive root (string, number, Boolean, null)NoRejected: there is no stable column model
JSON with comments or trailing commasNoRejected by the strict parser
JSON with duplicate keysAcceptedDuplicates collapse per standard JSON parsing; do not rely on them as data

If your data is a single primitive or an array of primitives, the conversion has no meaningful destination and the converter tells you so. Transform the input into objects first, then re-run.

Convert JSON to HTML table in the browser

This is the core workflow when you want to render JSON as a static, paste-ready table fragment instead of building one in JavaScript at runtime.

  1. Paste one strict JSON object, or a non-empty array of objects, into the converter's input area.
  2. Run the conversion and inspect the union columns, missing cells, null values, nested JSON text, and the escaped preview.
  3. Verify that the first row's key order matches what you expect; later records only contribute previously unseen keys, so reordering the source array changes the column order.
  4. Copy the HTML fragment from the converter.
  5. Add a destination-specific caption, any required CSS, and the surrounding document context (heading, intro paragraph, link to the source) in the page that will host the table.
  6. Test the final page in a real browser, confirm that <script> or <img onerror> strings render as visible text rather than executing, and check the destination's Content Security Policy and accessibility requirements.

If you need a non-HTML destination, the same source feeds related local tools. CSV to HTML Table Converter covers the same output shape when your data is already comma-delimited, and a CSV pipeline can also be the right call when downstream readers expect a spreadsheet rather than markup.

How columns, missing keys, and nulls are handled

Columns are the union of own enumerable keys in the order they first appear. The keys exposed by the first record appear first, and any new key discovered in a later record is appended to the right. That determinism matters because the alternative — sorting keys alphabetically, or reshuffling columns per row — produces a table that is harder to style and harder to read across rows.

The converter distinguishes three states for a cell. A missing key on a record becomes an empty td, because the property never existed on that object. An explicit JSON null becomes the literal text null, so absence and a real null do not silently collapse into the same output. Strings stay strings, numbers and Booleans use their JSON-readable spelling, and nested arrays or objects become compact JSON text inside one cell. The fragment therefore never invents a relational row count or a Cartesian product from nested arrays — nested data is represented, not expanded.

If the destination needs flattened rows, normalized child tables, dot-path column names like address.city, or one row per nested item, transform the data against an explicit schema before you paste it in. The converter is intentionally a presentation step, not a schema engine, and pre-transforming is faster than re-parsing after the fact.

Escaping and the React preview boundary

Every header and cell is encoded for HTML text context before it is placed between th or td tags. Ampersands, less-than signs, greater-than signs, double quotes, and apostrophes are escaped, so a value such as <script>alert(1)</script> appears as visible text instead of becoming a tag. The escaping aligns with the encoding rules in the WHATWG HTML syntax specification and the OWASP XSS Prevention Cheat Sheet guidance for untrusted content placed in HTML body text.

The on-page preview adds a second boundary. The React preview is built from text nodes using the original cell values, not by injecting the generated HTML with innerHTML. That means even if a future regression broke the escaping in the copied fragment, the preview itself would still render strings as text. The two layers are independent on purpose, so the copy step is the place to re-verify the fragment before it reaches its real destination, especially on destinations that re-render or sanitize markup differently than a browser does.

Limits and what to do when you outgrow them

The converter fails instead of truncating. The exact ceilings are fixed, and the tool refuses to produce partial output if any of them is exceeded.

LimitCapWhat to do instead
Input size500,000 charactersSplit the file or pre-filter to the records you actually need
Rows10,000Page the data, sample it, or move to a server-side table
Columns200Reshape to fewer columns or split into multiple tables
Output size5,000,000 charactersNarrow the visible fields before converting

Eight external fixtures cover strings, numbers, Booleans, null, HTML-sensitive text, quotes, nested arrays, and disjoint object keys, so the conversion has been checked against the most common value shapes. If your real data is well outside those fixtures, pre-validate with JSON Validator to confirm the parser is happy before you paste it in.

When to transform JSON before converting

Two patterns are worth doing as a separate step rather than asking the converter to guess. First, if some records have deeply nested children that need their own table, build those normalized child arrays on your own — the converter keeps nested data in one cell by design, and that decision is what keeps the column model deterministic. Second, if duplicate keys are load-bearing in your source text, rewrite the input first. Standard JSON parsing resolves duplicate member names before the table is generated, so the converter cannot preserve them, and treating duplicates as data is a brittle habit anyway.

For runtime, client-side tables that react to live data, this tool is the wrong layer: it produces a static fragment, not a renderer. Reach for a templating step or a small framework component when you need reactivity, sorting, or filtering. For everything else — a documentation page, a release-notes table, an email draft, a static prototype — pasting JSON into the JSON to HTML Table Converter, copying the fragment, and adding your own caption and styles is the shortest path from data to table without inviting XSS into your page.

For a deeper look, see Will the Output Compile Without Dependencies: JSON to Rust.

For a deeper look, see Is JSON to XML Safe to Use Online? A Browser-Side Guide.