CtrlK
BlogDocsLog inGet started
Tessl Logo

with-tanstack-virtual

Virtualize Solid Table row/column models and infinite Query data with createVirtualizer, reactive counts, scroll targets, stable keys, dynamic measurement, transforms, sticky regions, and grid/flex sizing. Load for Solid tracking or layout bugs.

66

Quality

81%

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

SKILL.md
Quality
Evals
Security

This skill builds on @tanstack/table-core#core, getting-started, and table-state. Virtualize the final Table model in the renderer; Virtual is not a Table feature.

Setup

import { createVirtualizer } from '@tanstack/solid-virtual'

let scrollElement: HTMLDivElement | undefined
const rows = () => table.getRowModel().rows
const virtualizer = createVirtualizer({
  get count() {
    return rows().length
  },
  getScrollElement: () => scrollElement ?? null,
  estimateSize: () => 36,
  getItemKey: (index) => rows()[index].id,
  overscan: 5,
})

Core Patterns

Keep count reactive

const virtualizer = createVirtualizer({
  get count() {
    return rows().length
  },
  getScrollElement,
  estimateSize,
})

Apply measurement and geometry together

<tr
  data-index={item.index}
  ref={(node) => virtualizer.measureElement(node)}
  style={{ position: 'absolute', transform: `translateY(${item.start}px)` }}
/>

Common Mistakes

HIGH Snapshotting row count

Wrong:

createVirtualizer({ count: rows().length, getScrollElement, estimateSize })

Correct:

createVirtualizer({
  get count() {
    return rows().length
  },
  getScrollElement,
  estimateSize,
})

The getter lets Solid Virtual track changes to the final row model.

Source: examples/solid/virtualized-rows

HIGH Virtualizing raw data

Wrong:

const rows = () => data()

Correct:

const rows = () => table.getRowModel().rows

Raw data excludes Table's current sorting, filtering, grouping, expansion, and pagination.

Source: docs/framework/solid/guide/virtualization.md

HIGH Separating ref lifecycle from virtualizer

Wrong:

const scrollElement = document.querySelector('#rows')
const virtualizer = createVirtualizer({
  getScrollElement: () => scrollElement,
  count: 100,
  estimateSize,
})

Correct:

let scrollElement: HTMLDivElement | undefined
const virtualizer = createVirtualizer({
  getScrollElement: () => scrollElement ?? null,
  get count() {
    return rows().length
  },
  estimateSize,
})

Keep the ref and virtualizer in the same owner so observers attach after JSX assigns the element.

Source: examples/solid/virtualized-rows

HIGH Omitting renderer geometry

Wrong:

<For each={virtualizer.getVirtualItems()}>
  {(item) => <tr>{rows()[item.index].id}</tr>}
</For>

Correct:

<tbody
  style={{ height: `${virtualizer.getTotalSize()}px`, position: 'relative' }}
>
  <For each={virtualizer.getVirtualItems()}>
    {(item) => (
      <tr
        style={{
          position: 'absolute',
          transform: `translateY(${item.start}px)`,
        }}
      >
        {rows()[item.index].id}
      </tr>
    )}
  </For>
</tbody>

Virtual computes positions; the renderer must apply spacer size, transforms, widths, and sticky CSS.

Source: examples/solid/virtualized-rows

API Discovery

Inspect node_modules/@tanstack/solid-table/dist/index.d.ts and installed node_modules/@tanstack/solid-virtual/dist/; use the maintained row, column, or infinite example for the matching CSS geometry contract.

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.