npx skills add ...
npx skills add skilld-dev/vue-ecosystem-skills --skill tanstack-vue-table-skilld
Use when writing, migrating, or debugging code that imports @tanstack/vue-table (TanStack Table v9 for Vue). Covers useTable with explicit tableFeatures, reactive ref/computed data, FlexRender rendering, atoms-based state, createTableHook conventions, and the v8-to-v9 breaking changes.
npx skills add skilld-dev/vue-ecosystem-skills --skill tanstack-vue-table-skilld
Headless table adapter for Vue 3. Re-exports all of @tanstack/table-core 9.2.4 plus Vue bindings: useTable, FlexRender, flexRender, createTableHook (dist/index.d.ts:4-5).
Environment limits: vue >=3.2 peer dependency, Node >=20, runtime dep @tanstack/store ^0.11.1 (package.json:34-53).
This Skill targets v9 only. Code using useVueTable, getCoreRowModel(), or onStateChange is v8; migrate it first with Migration v8 to v9.
Source: skills/getting-started/SKILL.md (shipped in the package).
Every feature beyond core must be registered, and each row-model slot follows its prerequisite feature in the same tableFeatures call. The core row model is automatic; there is no getCoreRowModel() option.
APIs are feature-gated: a missing table.atoms.pagination means rowPaginationFeature was not registered. Full feature and slot list: API surface.
State is atom-based. Read it inside a tracked boundary (template, computed, watch, or table.Subscribe); a bare read is only a snapshot.
Controlled slices need a reactive state plus the matching on[State]Change callback that resolves value-or-function updaters:
Own each slice exactly once: internal default, initialState, external atoms, or state + callback. Never both atoms.pagination and state.pagination. onStateChange no longer exists; observe table.store instead. Details: API surface.
data as a ref/computed, never data.value (dist/useTable.d.ts:13-19). Update it by replacing the array (.value = [...]); in-place push/splice is not tracked because writable atoms use shallowRef (dist/reactivity.js:50-52).features and columns stable; do not rebuild arrays per render.FlexRender shorthand: :cell, :header, :footer. The legacy :render/:props form still compiles but is the migration target, not the default (dist/FlexRender.d.ts:28-41).this. Use row.getValue('name'), not const read = row.getValue.table.Subscribe its render function as the explicit children prop; Vue JSX children become slots (dist/useTable.d.ts:9-11).manual* option (manualPagination: true) and pass rowCount.stockFeatures bundles everything; use it only as a temporary audit bridge, not production.useVueTable to useTable while keeping getSortedRowModel options. Move row models and registries into tableFeatures (skills/migrate-v8-to-v9/SKILL.md:156-159).useTable({ data: data.value }) freezes one snapshot; pass data (skills/getting-started/SKILL.md:85-99).table.atoms.sorting.get() outside a tracked boundary; wrap in computed (skills/table-state/SKILL.md:104-116).pagination.value = next) instead of resolving it first (skills/table-state/SKILL.md:146-161).columnPinning.left/right no longer exist; v9 uses start/end logical pinning (skills/migrate-v8-to-v9/SKILL.md:99-120).createColumnHelper<Person>() now needs features first: createColumnHelper<typeof features, Person>() (skills/migrate-v8-to-v9/SKILL.md:147-148).For app-wide table defaults, use createTableHook({ features, tableComponents, cellComponents, headerComponents }) to get useAppTable, createAppColumnHelper, and typed context hooks (dist/createTableHook.d.ts:136-153). Export the context hook with an explicit type to avoid circular inference when registered components import the hook module (skills/create-table-hook/SKILL.md:62-84).
rowCount, computed data passthrough. Integrationstable.getRowModel().rows, never the source array. IntegrationsuseTable/Subscribe types, features and slots, atoms model.The package ships its own agent skills under skills/ (getting-started, table-state, migrate-v8-to-v9, create-table-hook, with-tanstack-query, with-tanstack-virtual) and mentions npx @tanstack/intent@latest install to wire them into coding agents (README.md:70-78). Verify exact APIs in the installed node_modules/@tanstack/vue-table/dist/index.d.ts; do not reconstruct v9 from v8 memory.
import {
createSortedRowModel,
rowSortingFeature,
sortFn_alphanumeric,
tableFeatures,
} from '@tanstack/vue-table'
const features = tableFeatures({
rowSortingFeature,
sortedRowModel: createSortedRowModel(),
sortFns: { alphanumeric: sortFn_alphanumeric },
})const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)const pagination = ref<PaginationState>({ pageIndex: 0, pageSize: 20 })
const state = computed(() => ({ pagination: pagination.value }))
const onPaginationChange = (next: PaginationState | ((old: PaginationState) => PaginationState)) => {
pagination.value = typeof next === 'function' ? next(pagination.value) : next
}
// pass state and onPaginationChange to useTable