Shadcn React Table

Search documentation

Search the docs

Virtualization

Virtualization renders only the cells currently in view, keeping large tables fast. The data table supports both row and column virtualization.

Row virtualization

Set enableRowVirtualization: true to render only the visible rows. This is recommended once you have more than roughly 100 rows.

Virtualized (1,000 rows)
GitHub
ID
$89,671,500

With row virtualization on, the table surface becomes the scroll container, so give it a bounded height via surfaceClassName (it defaults to max-h-[600px]).

import { DataTable, useDataTable } from "@/components/ui/data-table"

const table = useDataTable({
  data,
  columns,
  getRowId: (row) => row.id,
  enableRowVirtualization: true,
  surfaceClassName: "max-h-[600px]",
  estimateRowHeight: 52,
  virtualOverscan: 8,
})

return <DataTable table={table} />

Tune the behavior with estimateRowHeight (default 52) and virtualOverscan (default 8, the number of extra rows rendered above and below the viewport).

Advanced virtualizer control

For finer control, both virtualizers expose the underlying @tanstack/react-virtual API.

Pass rowVirtualizerOptions / columnVirtualizerOptions to merge extra options into the useVirtualizer call. They override the built-in count, estimateSize, overscan, and measureElement, and accept either an object or a ({ table }) => options function:

const table = useDataTable({
  data,
  columns,
  enableRowVirtualization: true,
  rowVirtualizerOptions: { overscan: 12, gap: 4 },
})

To drive the virtualizer imperatively (for example, to scroll to a row), pass a ref via rowVirtualizerInstanceRef / columnVirtualizerInstanceRef:

import { useRef } from "react"
import type { DataTableRowVirtualizer } from "@/components/ui/data-table"

const rowVirtualizerRef = useRef<DataTableRowVirtualizer>(null)

const table = useDataTable({
  data,
  columns,
  enableRowVirtualization: true,
  rowVirtualizerInstanceRef: rowVirtualizerRef,
})

// later, e.g. in an effect or event handler:
rowVirtualizerRef.current?.scrollToIndex(100)

Row drag-ordering is disabled

Row virtualization is incompatible with row drag-ordering. If you need to reorder rows by dragging, leave virtualization off. See Row ordering.

Column virtualization

For very wide tables, set enableColumnVirtualization: true to virtualize columns. This applies fixed column widths and is not combined with column pinning or column ordering.

Column virtualization
GitHub
import { DataTable, useDataTable } from "@/components/ui/data-table"

const table = useDataTable({
  data,
  columns,
  getRowId: (row) => row.id,
  enableColumnVirtualization: true,
  enablePagination: false,
})

return <DataTable table={table} />

Pair with no pagination

Column virtualization is usually paired with enablePagination: false so all rows scroll within one virtualized surface.

Relevant options

PropTypeDefaultDescription
enableRowVirtualization?booleanfalseVirtualize body rows for large datasets (recommended past ~100 rows). The table surface becomes the scroll container — give it a bounded height via `className`/`style` (defaults to `max-h-[600px]`). Disables row DnD.
enableColumnVirtualization?booleanfalseVirtualize columns for very wide tables. Applies fixed column widths and is not combined with column pinning/ordering.
estimateRowHeight?number52Estimated row height (px) for the virtualizer. Default 52.
virtualOverscan?number8Extra rows rendered above/below the viewport. Default 8.
rowVirtualizerOptions?RowVirtualizerOptions<TData>Partial `@tanstack/react-virtual` options merged into the row virtualizer (overrides the built-in `count`/`estimateSize`/`overscan`/`measureElement`). Accepts an object or a `({ table }) => options` function.
columnVirtualizerOptions?ColumnVirtualizerOptions<TData>Partial `@tanstack/react-virtual` options merged into the column virtualizer. Accepts an object or a `({ table }) => options` function.
rowVirtualizerInstanceRef?React.RefObject<DataTableRowVirtualizer | null>Ref populated with the row `Virtualizer` instance for imperative control (e.g. `scrollToIndex`). Only set when `enableRowVirtualization`.
columnVirtualizerInstanceRef?React.RefObject<DataTableColumnVirtualizer | null>Ref populated with the column `Virtualizer` instance. Only set when `enableColumnVirtualization`.