with-tanstack-virtual
SkillAI & modelsLets your agent render long React table lists efficiently using the tanstack claude skill for virtualized rows.
Use with-tanstack-virtual in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add with-tanstack-virtual and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the with-tanstack-virtual skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
About this skill
Virtualize final React Table row or column models with TanStack Virtual. Load for useVirtualizer counts, scroll elements, stable keys, data-index measurement, dynamic heights, sticky headers/columns, grid/flex geometry, or infinite fetching; Virtual is renderer composition, not a Table feature.
What this skill tells your AI
The instructions your AI receives, as published by octanejs/octane in packages/tanstack-table/upstream/skills/with-tanstack-virtual/SKILL.md and read by Ahel’s review.
This skill builds on @tanstack/table-core#core, getting-started, and table-state. Build the Table model first, then virtualize its final rendered rows or visible columns.
Setup
import { useRef } from 'react'
import { useVirtualizer } from '@tanstack/react-virtual'
function VirtualBody({ table }: { table: any }) {
const scrollRef = useRef<HTMLDivElement>(null)
const rows = table.getRowModel().rows
const virtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => 36,
getItemKey: (index) => rows[index].id,
overscan: 5,
})
return (
<div ref={scrollRef} style={{ height: 400, overflow: 'auto' }}>
<div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
{virtualizer.getVirtualItems().map((item) => (
<div
key={rows[item.index].id}
data-index={item.index}
ref={virtualizer.measureElement}
style={{
position: 'absolute',
transform: `translateY(${item.start}px)`,
width: '100%',
}}
>
{rows[item.index].getAllCells().map((cell: any) => (
<span
key={cell.id}
style={{
display: 'inline-block',
width: cell.column.getSize(),
}}
>
<table.FlexRender cell={cell} />
</span>
))}
</div>
))}
</div>
</div>
)
}
Core Patterns
Keep the virtualizer near its render loop
const rows = table.getRowModel().rows
const rowVirtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => container.current,
estimateSize: () => 36,
})
This limits unrelated parent updates and keeps count, measurement, and rendered items together.
Use Table sizes in renderer CSS
<td style={{ width: cell.column.getSize() }}>
<table.FlexRender cell={cell} />
</td>
Table calculates size state; the renderer must apply it.
Common Mistakes
HIGH Registering Virtual as a feature
Wrong:
const features = tableFeatures({ rowVirtualizer: useVirtualizer(options) })
Correct:
const rows = table.getRowModel().rows
const virtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => 36,
})
Virtual controls rendering geometry and is not a Table feature or row model.
Source: docs/framework/react/guide/virtualization.md
HIGH Virtualizing raw input data
Wrong:
const virtualizer = useVirtualizer({
count: data.length,
getScrollElement,
estimateSize,
})
Correct:
const rows = table.getRowModel().rows
const virtualizer = useVirtualizer({
count: rows.length,
getScrollElement,
estimateSize,
})
Raw data ignores filtering, sorting, expansion, grouping, and pagination already applied by Table.
Source: examples/react/virtualized-rows
HIGH Measuring against incomplete identity
Wrong:
<tr ref={virtualizer.measureElement}>{row.id}</tr>
Correct:
<tr key={row.id} data-index={item.index} ref={virtualizer.measureElement}>
{row.id}
</tr>
Dynamic measurement needs the virtual index, and stable row identity prevents measurements moving to the wrong row.
Source: examples/react/virtualized-rows
HIGH Omitting positioning geometry
Wrong:
<tbody>{virtualizer.getVirtualItems().map(renderRow)}</tbody>
Correct:
<tbody
style={{
display: 'grid',
height: virtualizer.getTotalSize(),
position: 'relative',
}}
>
{virtualizer.getVirtualItems().map(renderRow)}
</tbody>
Virtual only computes positions; the renderer must provide total spacer size and position items using each virtual start.
Source: examples/react/virtualized-rows
API Discovery
Inspect node_modules/@tanstack/react-table/dist/index.d.ts for Table render APIs and installed node_modules/@tanstack/react-virtual/dist/ for the exact virtualizer options. Copy layout contracts from the maintained example matching rows, columns, or infinite loading.
Signals
- GitHub stars
- 1k
- Forks
- 61
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
with-tanstack-virtual- Source
- github.com/octanejs/octane
Related picks
Skill · davila7
The pick for Reactreact-doctor
Skill · millionco
The pick for Reactsetup-ts-deep-modules
Skill · mattpocock
The pick for TypeScripttypescript-pro
Skill · jeffallan
The pick for TypeScriptskill-creator
Skill · anthropics
More in AI & modelstriage
Skill · mattpocock
More in AI & models