Renders arbitrary JSON as a nested, recursive HTML table.
Open in| id | name | active | |
|---|---|---|---|
1 | "Ada Lovelace" | "ada@example.com" | true |
2 | "Grace Hopper" | "grace@example.com" | true |
3 | "Alan Turing" | "alan@example.com" | false |
npx shadcn@latest add https://json-table.kaylee.jp/r/json-table.jsonUsage
Basic usage
Import from where the CLI installed it and pass your data.
import { JsonTable } from "@/components/ui/json-table"
const data = {
id: 1,
name: "Ada Lovelace",
active: true,
}
export function Example() {
return <JsonTable data={data} />
}
Styling and depth limit
className passes through; maxDepth guards against pathologically deep data.
import { JsonTable } from "@/components/ui/json-table"
export function Example({ data }: { data: unknown }) {
return <JsonTable data={data} className="max-w-2xl" maxDepth={5} />
}
Localizing keys
keyTranslations maps a key name to a label. Values are never translated.
import { JsonTable } from "@/components/ui/json-table"
const keyTranslations = {
name: "名前",
email: "メール",
}
export function Example({ data }: { data: unknown }) {
return <JsonTable data={data} keyTranslations={keyTranslations} />
}
Custom type colors
primitiveClassNames overrides the per-type value styling — pass your own classes, including theme tokens if your base color has distinguishable hues.
import { JsonTable } from "@/components/ui/json-table"
const primitiveClassNames = {
string: "text-chart-1",
number: "text-chart-2",
boolean: "text-chart-4",
}
export function Example({ data }: { data: unknown }) {
return <JsonTable data={data} primitiveClassNames={primitiveClassNames} />
}
Examples
Flat object
Primitives, null, and undefined are each styled distinctly.
| id | 42 |
| name | "Ada Lovelace" |
| active | true |
| nickname | null |
| title | undefined |
Raw JSON
{
"id": 42,
"name": "Ada Lovelace",
"active": true,
"nickname": null
}Localized keys
keyTranslations maps a key to a label. Values are never translated.
| ID | 名前 | メール | 有効 |
|---|---|---|---|
1 | "Ada Lovelace" | "ada@example.com" | true |
2 | "Grace Hopper" | "grace@example.com" | true |
3 | "Alan Turing" | "alan@example.com" | false |
Raw JSON
[
{
"id": 1,
"name": "Ada Lovelace",
"email": "ada@example.com",
"active": true
},
{
"id": 2,
"name": "Grace Hopper",
"email": "grace@example.com",
"active": true
},
{
"id": 3,
"name": "Alan Turing",
"email": "alan@example.com",
"active": false
}
]Custom type colors
primitiveClassNames overridden here with this site's own chart tokens. Whether tokens stay colorful depends on the consumer's base color — plain Tailwind colors (the default) always are.
| id | 42 |
| name | "Ada Lovelace" |
| active | true |
| nickname | null |
| title | undefined |
Raw JSON
{
"id": 42,
"name": "Ada Lovelace",
"active": true,
"nickname": null
}Array of objects with missing keys
Columns are the union of every item's keys.
| id | name | role | team |
|---|---|---|---|
1 | "Ada Lovelace" | "Engineer" | — |
2 | "Grace Hopper" | — | — |
3 | "Alan Turing" | "Researcher" | "Cryptography" |
Raw JSON
[
{
"id": 1,
"name": "Ada Lovelace",
"role": "Engineer"
},
{
"id": 2,
"name": "Grace Hopper"
},
{
"id": 3,
"name": "Alan Turing",
"role": "Researcher",
"team": "Cryptography"
}
]Arrays of primitives
Rendered inline rather than as a sub-table.
| tags | "math", "computing", "history" |
| scores | 98, 87, 91, 76 |
Raw JSON
{
"tags": [
"math",
"computing",
"history"
],
"scores": [
98,
87,
91,
76
]
}Deep nesting
Objects, arrays, and objects again, several levels deep.
| organization | "Analytical Engines Inc." | ||||||||||||||||||||
| departments |
|
Raw JSON
{
"organization": "Analytical Engines Inc.",
"departments": [
{
"name": "Engineering",
"headcount": 12,
"lead": {
"name": "Ada Lovelace",
"email": "ada@example.com"
},
"tags": [
"core",
"infra"
]
},
{
"name": "Research",
"headcount": 4,
"lead": {
"name": "Alan Turing",
"email": "alan@example.com"
},
"tags": [
"theory"
]
}
]
}Edge cases
Empty object/array, a mixed-type array, and a wide table.
| emptyObject | {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emptyArray | [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nullValue | null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mixedArray |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| wideTable |
|
Raw JSON
{
"emptyObject": {},
"emptyArray": [],
"nullValue": null,
"mixedArray": [
1,
"two",
{
"three": 3
},
[
4,
5
]
],
"wideTable": [
{
"field_1": 0,
"field_2": 7,
"field_3": 14,
"field_4": 21,
"field_5": 28,
"field_6": 35,
"field_7": 42,
"field_8": 49,
"field_9": 56,
"field_10": 63,
"field_11": 70,
"field_12": 77,
"field_13": 84,
"field_14": 91,
"field_15": 98,
"field_16": 105,
"field_17": 112,
"field_18": 119,
"field_19": 126,
"field_20": 133
},
"[Circular]"
]
}Circular reference
A JS object graph pointing back at itself renders [Circular] instead of hanging.
| name | "self-referencing" |
| self | [Circular] |
Raw JSON
{
"name": "self-referencing",
"self": "[Circular]"
}