TanStack logo

Skill

create-table-hook

create reusable Vue table hooks

Covers Vue UI Components Frontend

Description

Create a reusable Vue useAppTable/createAppColumnHelper with shared features/defaults, reactive per-table options, optional component registries, dynamic App wrappers, typed context hooks, and explicit types that break circular inference.

SKILL.md

This skill builds on @tanstack/table-core#core, getting-started, and table-state. Use it for recurring app conventions; use useTable for a one-off.

Setup

import {
  createTableHook,
  rowSortingFeature,
  tableFeatures,
} from '@tanstack/vue-table'
import type { RowData, VueTable } from '@tanstack/vue-table'

const features = tableFeatures({ rowSortingFeature })
const hook = createTableHook({ features })
export const useAppTable = hook.useAppTable
export const createAppColumnHelper = hook.createAppColumnHelper
export const useTableContext: <TData extends RowData = RowData>() => VueTable<
  typeof features,
  TData
> = hook.useTableContext

The explicit exported context-hook types are important when registered components import the hook module that also imports those components.

Core Patterns

Keep per-table values reactive

const helper = createAppColumnHelper<Person>()
const columns = helper.columns([helper.accessor('name', { header: 'Name' })])
const table = useAppTable({ columns, data })

Pass refs/computed options through unchanged.

Wrap registered component context

Render through table.AppTable, table.AppCell, or table.AppHeader; inside registered components call the corresponding typed context hook instead of prop drilling.

Common Mistakes

HIGH Creating circular inferred exports

Wrong:

export const { useAppTable, useTableContext } = createTableHook({
  tableComponents: { Pager },
})

Correct:

const hook = createTableHook({ tableComponents: { Pager } })
export const useTableContext: <TData extends RowData = RowData>() => VueTable<
  typeof features,
  TData
> = hook.useTableContext

When Pager imports useTableContext, inferred destructured exports can form a circular inference/import chain.

Source: docs/framework/vue/guide/composable-tables.md

HIGH Flattening reactive table options

Wrong:

useAppTable({ columns, data: data.value })

Correct:

useAppTable({ columns, data })

The app hook preserves the adapter’s MaybeRef option contract.

Source: packages/vue-table/src/createTableHook.ts

HIGH Using context without App wrappers

Wrong:

const table = useTableContext()

Correct:

<component :is="table.AppTable"><Pager /></component>

The typed context exists only below the corresponding dynamic wrapper.

Source: packages/vue-table/src/createTableHook.ts

MEDIUM Treating Subscribe children as slots

Wrong:

<table.Subscribe>
  {(atoms) => <Pager page={atoms.pagination.get()} />}
</table.Subscribe>

Correct:

<table.Subscribe
  children={(atoms) => <Pager page={atoms.pagination.get()} />}
/>

Vue’s adapter expects an explicit children prop in JSX.

Source: packages/vue-table/src/useTable.ts

API Discovery

Inspect node_modules/@tanstack/vue-table/dist/createTableHook.d.ts for the returned helpers, wrapper props, registry types, and context contracts.

© 2026 YourAI.tools. Every skill from an identity-verified publisher.

Independent catalog. Not affiliated with, endorsed by, or sponsored by Anthropic or any listed publisher. All trademarks belong to their respective owners.