Create and render a TanStack React Table v9 table with useTable, tableFeatures, stable data and columns, row/header models, and table.FlexRender. Load for a first React table, headless rendering, or when v8 useReactTable examples are producing the wrong setup.
72
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
This skill builds on @tanstack/table-core#core and @tanstack/table-core#table-features. Read them first for the headless model and explicit feature registration.
import { useMemo, useState } from 'react'
import {
createColumnHelper,
tableFeatures,
useTable,
} from '@tanstack/react-table'
type Person = { name: string; age: number }
const features = tableFeatures({})
const helper = createColumnHelper<typeof features, Person>()
const columns = helper.columns([
helper.accessor('name', { header: 'Name' }),
helper.accessor('age', { header: 'Age' }),
])
export function PeopleTable() {
const [data] = useState<Person[]>([{ name: 'Ada', age: 36 }])
const table = useTable({ features, columns, data })
return (
<table>
<thead>
{table.getHeaderGroups().map((group) => (
<tr key={group.id}>
{group.headers.map((header) => (
<th key={header.id}>
{header.isPlaceholder ? null : (
<table.FlexRender header={header} />
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getAllCells().map((cell) => (
<td key={cell.id}>
<table.FlexRender cell={cell} />
</td>
))}
</tr>
))}
</tbody>
</table>
)
}Table produces models and state; React owns the semantic markup, styles, event affordances, and accessibility.
import {
createSortedRowModel,
rowSortingFeature,
tableFeatures,
} from '@tanstack/react-table'
const sortableFeatures = tableFeatures({
rowSortingFeature,
sortedRowModel: createSortedRowModel(),
})Row-model slots belong inside tableFeatures, after their prerequisite feature.
const features = tableFeatures({})
const data: Person[] = [{ name: 'Ada', age: 36 }]Use state, memoization, or query results for changing data; avoid a new fallback array every render.
Wrong:
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})Correct:
const table = useTable({ data, columns, features })V9 uses useTable; optional row models are registered as feature slots rather than table options.
Source: docs/framework/react/guide/migrating.md
Wrong:
const features = tableFeatures({})Correct:
const features = tableFeatures({
rowSortingFeature,
sortedRowModel: createSortedRowModel(),
})Sorting state and methods do not exist until the sorting feature is registered.
Source: packages/table-core/src/TableFeatures.ts
Wrong:
const table = useTable({ features, columns, data: response.data ?? [] })Correct:
// module scope
const EMPTY_DATA: Person[] = []
const table = useTable({ features, columns, data: response.data ?? EMPTY_DATA })A fresh fallback invalidates data-dependent models on every render.
Source: docs/framework/react/guide/data.md
Inspect node_modules/@tanstack/react-table/dist/index.d.ts first, then the exported useTable.d.ts, FlexRender.d.ts, or core feature source. Use installed declarations so names match the consumer's exact v9 version.
9e523bc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.