CtrlK
BlogDocsLog inGet started
Tessl Logo

create-table-hook

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.

58

Quality

68%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./packages/vue-table/skills/create-table-hook/SKILL.md
SKILL.md
Quality
Evals
Security

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.

Repository
TanStack/table
Last updated
First committed

Is this your skill?

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.