A high-performance, feature-rich virtualized table component for React built on top of TanStack Table and TanStack Virtual. Inspired by professional grid libraries like Handsontable and AG Grid.
- π Virtualization: Efficiently render thousands of rows with smooth scrolling
- β¨οΈ Keyboard Navigation: Full keyboard support (Arrow keys, Tab, Enter, F2, Escape)
- βοΈ Cell Editing: Double-click or press Enter/F2 to edit cells inline
- π¨ Theming: Built-in light/dark themes with CSS variables for easy customization
- π Auto Column Sizing: Optional automatic column width calculation based on content
- π― Cell Selection: Click to select, double-click to edit
- π Column Sorting: Built-in column sorting support
- π Customizable: Extensive styling options and theme overrides
- π± Responsive: Works seamlessly across different screen sizes
npm install react-tanstack-virtual-tableor
yarn add react-tanstack-virtual-tableor
pnpm add react-tanstack-virtual-tableThis library requires React 18+ and the following peer dependencies:
npm install react react-dom @tanstack/react-table @tanstack/react-virtualImportant: Don't forget to import the CSS file! Add this import to your application entry point:
import "react-tanstack-virtual-table/dist/index.css";Then use the component:
import { VirtualTable } from "react-tanstack-virtual-table";
import type { ColumnDef } from "@tanstack/react-table";
type Person = {
name: string;
age: number;
email: string;
};
const data: Person[] = [
{ name: "John Doe", age: 30, email: "john@example.com" },
{ name: "Jane Smith", age: 25, email: "jane@example.com" },
// ... more data
];
const columns: ColumnDef<Person>[] = [
{
header: "Name",
accessorKey: "name",
},
{
header: "Age",
accessorKey: "age",
},
{
header: "Email",
accessorKey: "email",
},
];
function App() {
return <VirtualTable data={data} columns={columns} height={600} />;
}- Installation Guide
- Quick Start Guide
- Basic Examples
- Styling & Theming
- Cell Editing Guide
- API Reference
- FAQs
<VirtualTable data={data} columns={columns} height={400} /><VirtualTable
data={data}
columns={columns}
height={400}
readonly={false}
onCellValueChange={(rowIndex, columnId, value) => {
console.log(`Row ${rowIndex}, Column ${columnId}: ${value}`);
// Update your data here
}}
/><VirtualTable data={data} columns={columns} height={400} theme="dark" /><VirtualTable
data={data}
columns={columns}
height={400}
themeOverride={{
"--vt-bg": "#ffffff",
"--vt-border": "#e0e0e0",
"--vt-text": "#333333",
}}
/><VirtualTable
data={data}
columns={columns}
height={400}
autoFitColumnWidth={true}
autoFitOptions={{
minWidth: 80,
maxWidth: 400,
padding: 16,
}}
/>- Arrow Keys: Navigate between cells
- Tab / Shift+Tab: Move to next/previous cell (wraps to next row)
- Enter / F2: Enter edit mode for selected cell
- Escape: Exit edit mode (keeps selection)
- Click: Select a cell
- Double-Click: Select and edit a cell
The table uses row virtualization to efficiently render large datasets. Only visible rows are rendered in the DOM, ensuring smooth performance even with thousands of rows.
- Click a cell to select it (blue focus ring appears)
- Double-click or press Enter/F2 to enter edit mode
- Escape to exit edit mode
- The focus ring follows the selected/editing cell during scrolling
When a cell is selected or being edited:
- The corresponding column header is highlighted
- The row number in the left header is highlighted
Click on any column header to sort. Click again to reverse the sort order.
# Install dependencies
npm install
# Run development server
npm run dev
# Build library
npm run build
# Run Storybook (after setup)
npm run storybookMIT
Contributions are welcome! Please feel free to submit a Pull Request.