
Description
Read Vue-backed table.atoms/store in templates, computed, watch, or table.Subscribe; own slices with refs/computed or external Vue Store atoms; and apply updater callbacks while preserving reactive option shapes.
SKILL.md
This skill builds on @tanstack/table-core#core and getting-started. Read them first for state ownership and Vue construction.
State Mental Model
TanStack Table is primarily a state coordinator. Keep state internal unless another system needs to read, persist, or drive it. Without initialState, atoms, state, or on[State]Change, the table owns every registered slice.
table.baseAtomsare internal writable atoms created from resolved initial state.table.atomsare readonly derived atoms for the active owner of each registered slice.table.storecombines those atoms into one readonly flat store.
The Vue adapter backs atoms with refs/computed values and tracks reactive table options. Atom reads become reactive inside templates, computed, watch, or table.Subscribe; a read cached outside tracking is only a snapshot. State is feature-based, so a missing pagination atom or option means rowPaginationFeature was not registered. Keep features and columns stable; pass reactive data as a ref/computed instead of recreating arrays in table options.
Setup
import { computed, ref } from 'vue'
import {
rowPaginationFeature,
tableFeatures,
useTable,
} from '@tanstack/vue-table'
const features = tableFeatures({ rowPaginationFeature })
const data = ref([{ name: 'Ada' }])
const columns = [{ accessorKey: 'name' }]
const table = useTable({ features, columns, data })
const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)
Internal state is usually enough. Atom reads are reactive only when Vue evaluates them in a tracked template, computed, watch, or render boundary.
Core Patterns
Control a slice without losing updater semantics
import { computed, ref } from 'vue'
import type { PaginationState } from '@tanstack/vue-table'
const pagination = ref<PaginationState>({ pageIndex: 0, pageSize: 20 })
const controlledState = computed(() => ({ pagination: pagination.value }))
const onPaginationChange = (
next: PaginationState | ((old: PaginationState) => PaginationState),
) => {
pagination.value = typeof next === 'function' ? next(pagination.value) : next
}
Pass state: controlledState and onPaginationChange to useTable.
Use Subscribe as a render boundary
table.Subscribe({
children: (atoms) => <span>{atoms.pagination.get().pageIndex + 1}</span>,
})
In Vue JSX, children is an explicit prop, not a slot child.
Choose State Ownership
Use exactly one owner per slice:
- Prefer internal state and feature methods for table-local behavior.
- Use
initialStatefor starting/reset values; changing it later does not reset current state. - Prefer a stable
@tanstack/vue-storeatom inatomsfor cross-system ownership. Feature APIs update it directly, so omiton[State]Change. - Use a ref/computed
statevalue plus the matching callback for simple controlled state. Preserve the reactive wrapper and resolve raw values and updater functions.
External atoms take precedence over external state, which syncs into the internal base atom. Do not configure multiple owners. The global v8 onStateChange option is gone; observe table.store if all state changes matter.
Initialize, Update, and Reset
Use feature methods such as setSorting, nextPage, toggleVisibility, and toggleSelected. Direct baseAtoms writes are a rare escape hatch for internally owned state; write the external atom when it owns the slice.
table.resetSorting()
table.resetPagination()
table.resetPagination(true)
Feature resets use table.initialState unless true requests the feature default and can update external owners. Core table.reset() only resets internal base atoms. Use slice types such as PaginationState; use TableState<typeof features> for the complete feature-inferred state.
Common Mistakes
HIGH Reading an untracked snapshot
Wrong:
const pageIndex = table.atoms.pagination.get().pageIndex
Correct:
const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)
The first read is current but does not make its consumer reactive.
Source: docs/framework/vue/guide/table-state.md
HIGH Passing state.value once
Wrong:
const table = useTable({
features,
columns,
data,
state: controlledState.value,
})
Correct:
const table = useTable({ features, columns, data, state: controlledState })
The adapter watches the computed ref; a one-time .value breaks future option synchronization.
Source: packages/vue-table/src/useTable.ts
HIGH Assigning updater functions as values
Wrong:
const onPaginationChange = (next) => {
pagination.value = next
}
Correct:
const onPaginationChange = (next) => {
pagination.value = typeof next === 'function' ? next(pagination.value) : next
}
Table callbacks accept either a value or a function of the previous value.
Source: examples/vue/basic-external-state/src/App.tsx
MEDIUM Supplying JSX children as a slot
Wrong:
<table.Subscribe>
{(atoms) => <span>{atoms.pagination.get().pageIndex}</span>}
</table.Subscribe>
Correct:
<table.Subscribe
children={(atoms) => <span>{atoms.pagination.get().pageIndex}</span>}
/>
The Vue adapter declares Subscribe(props: { children }) and expects the explicit prop.
Source: packages/vue-table/src/useTable.ts
API Discovery
Inspect node_modules/@tanstack/vue-table/dist/useTable.d.ts and reactivity.d.ts; inspect the exact state slice in the installed core feature directory.
More skills from the table repository
View all 29 skillsaggregation
perform data aggregation in TanStack Table
Jul 20Data AnalysisFrontendTanStackapi-not-found
diagnose TanStack Table API errors
Jul 20DebuggingFrontendTanStackclient-vs-server
manage TanStack Table data pipelines
Jul 20Data PipelineFrontendPerformanceTanStackcolumn-faceting
build faceted filter UIs
Jul 20Data VisualizationFrontendTanStackcolumn-filtering
implement column filtering in TanStack Table
Jul 20Data AnalysisFrontendTanStackcolumn-ordering
manage TanStack Table column ordering
Jul 20FrontendTanStackUI Components
More from TanStack
View publishercolumn-pinning
configure column pinning in TanStack Table
table
Jul 20CSSFrontendTanStackUI Componentscolumn-resizing
implement column resizing in TanStack Table
table
Jul 20FrontendTanStackUI Componentscolumn-sizing
configure column sizing in TanStack Table
table
Jul 20CSSFrontendTanStackUI Componentscolumn-visibility
manage column visibility in TanStack Table
table
Jul 20FrontendTanStackUI Componentscore
build data grids with TanStack Table
table
Jul 20Data AnalysisFrontendUI Componentscreate-table-hook
create reusable Vue table hooks
table
Jul 20FrontendUI ComponentsVue