Overview of Virtuoso Data Table
TableVirtuoso for users who require a dedicated table-specific API rather than a general virtualized HTML table primitive.website·Indexed 34 days ago
https://virtuoso.devDocumentation for Virtuoso, a suite of React components for rendering large datasets. Includes react-virtuoso for virtualized lists with variable-sized items, a high-performance Data Table with support for column resizing, reordering, and sticky columns, and a specialized Message List for chat-like interfaces with imperative scrolling and item identity management.
TableVirtuoso for users who require a dedicated table-specific API rather than a general virtualized HTML table primitive.Virtuoso packages provide Agent Skills—structured guidance designed to teach coding agents how to use the libraries correctly. These skills prevent agents from relying on outdated training data or habits from other virtualization libraries by providing component selection rules, measurement constraints, common pitfalls, and full package documentation.
Available skills include:
react-virtuoso: Covers virtualized lists, grids, and tables (Virtuoso, GroupedVirtuoso, VirtuosoGrid, TableVirtuoso).message-list: Covers chat and AI conversation UIs (VirtuosoMessageList).data-table: Covers the virtualized data grid (@virtuoso.dev/data-table).reactive-engine: Covers the @virtuoso.dev/reactive-engine-* state management family.Virtuoso Masonry is a virtualized masonry layout component for React. It is designed to arrange items in a grid with varying heights while maintaining high performance for large datasets by only rendering visible items. Key features include:
Virtuoso Message List is a virtualized React component built for human/chatbot conversations. It optimizes performance for large message histories by rendering only visible items. Key features include:
localModel) and a declarative column structure using DataTableColumn, DataTableColumnHeader, and DataTableCell.import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table'
import { localModel } from '@virtuoso.dev/data-table'
const rows = Array.from({ length: 40 }, (_, index) => ({
id: `SKU-${String(index + 1).padStart(3, '0')}`,
name: `Product ${index + 1}`,
category: ['Office', 'Peripherals', 'Audio'][index % 3]!,
status: ['In stock', 'Low stock', 'Backorder'][index % 3]!,
}))
const model = localModel({ data: rows })
export default function App() {
return (
<DataTable
className="rounded-xl"
computeRowKey={({ data }) => data.id}
model={model}
style={{ height: 340 }}
>
<DataTableColumn field="name">
<DataTableColumnHeader>Name</DataTableColumnHeader>
<DataTableCell>
{({ row }) => (
<div className="flex flex-col">
<span className="font-medium">{row.data.name}</span>
<span className="text-xs text-muted-foreground">{row.data.id}</span>
</div>
)}
</DataTableCell>
</DataTableColumn>
<DataTableColumn field="category">
<DataTableColumnHeader>Category</DataTableColumnHeader>
<DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
</DataTableColumn>
<DataTableColumn field="status" sticky="right">
<DataTableColumnHeader>Status</DataTableColumnHeader>
<DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
</DataTableColumn>
</DataTable>
)
}Column width in the DataTable consists of two parts: the base width and the realized width.
DataTableColumnHeader. This width serves as the starting point for both the header and every body cell in that column.grow settings.ListScrollLocation type provides detailed metrics about the list's position relative to the viewport and the scroll element. This is useful for implementing 'scroll to bottom' logic or detecting when the user has reached the end of the list.interface ListScrollLocation {
bottomOffset: number; // Distance between scroller bottom edge and viewport bottom edge (0 = at bottom)
isAtBottom: boolean; // True if list is at the bottom or currently scrolling to the bottom
lastItemBottomOffset: number; // Pixel distance from last visible item bottom edge to viewport bottom
lastVisibleItemIndex: number; // Index of the bottom-most item visible in the viewport
listOffset: number; // Distance between list top edge and viewport top edge (negative when scrolling down)
scrollHeight: number; // Total scroll height of the scroller wrapper
visibleListHeight: number; // Height of the visible list portion excluding headers/footers
}<VirtuosoGrid
totalCount={1000}
itemContent={(index) => <div className="grid-item">Item {index}</div>}
listClassName="grid-container"
/>The @virtuoso.dev/data-table installation via shadcn splits the library into two parts: a wrapper and a headless package.
@/components/ui/data-table): This is code copied into your repository. It owns the presentation layer, including Tailwind classes, default components (rows, headers, loading states), and ergonomic component names. You can edit these files directly to change the look and feel without affecting the table's logic.@virtuoso.dev/data-table): This is the installed dependency that owns the behavior, including virtualization, scrolling, the reactive engine, and data models (localModel, remoteModel).import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table'
import { localModel } from '@virtuoso.dev/data-table'
const rows = [
{ product: 'Standing Desk', owner: 'Avery', status: 'Launch ready' },
{ product: 'USB-C Dock', owner: 'Morgan', status: 'In review' },
{ product: 'Mechanical Keyboard', owner: 'Riley', status: 'Backorder' },
]
const model = localModel({ data: rows })
export default function App() {
return (
<DataTable model={model} style={{ height: 280 }}>
<DataTableColumn field="product">
<DataTableColumnHeader>Product</DataTableColumnHeader>
<DataTableCell className="font-medium">{({ cellValue }) => String(cellValue)}</DataTableCell>
</DataTableColumn>
<DataTableColumn field="owner">
<DataTableColumnHeader>Owner</DataTableColumnHeader>
<DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
</DataTableColumn>
<DataTableColumn field="status">
<DataTableColumnHeader>Status</DataTableColumnHeader>
<DataTableCell>
{({ cellValue }) => <span className="rounded-full bg-muted px-2 py-1 text-xs font-medium">{String(cellValue)}</span>}
</DataTableCell>
</DataTableColumn>
</DataTable>
)
}Render functions for cells and headers receive a parameter object providing context about the current row and column.
Cell Render Parameters (CellRenderParams):
cellValue: The value of the field for the current row (or result of an accessor).row: The full virtualized row object; use row.data for multi-field dependencies.column: The column definition.columnKey: Internal key for the column instance.columnState: Runtime state (e.g., { sticky: boolean }).overlaidByScrollbar: Boolean indicating if a native OS scrollbar overlaps the cell edge.Header Render Parameters (ColumnHeaderRenderParams):
Includes all the above except cellValue and row.
type CellRenderParams = {
cellValue: unknown
row: RowItem
column: ColumnDefinition
columnKey: string
columnState: ColumnState // e.g., { sticky: boolean }
overlaidByScrollbar: boolean
}
type ColumnHeaderRenderParams = Omit<CellRenderParams, 'cellValue' | 'row'><GroupedTableVirtuoso
groupCounts={[10, 20, 15]}
groupContent={(index) => (
<td colSpan={2}>Group {index}</td>
)}
itemContent={(index, groupIndex) => (
<>
<td>Item {index}</td>
<td>Group {groupIndex}</td>
</>
)}
/>