A production-ready, highly customizable React table component built with TanStack Table, Radix UI, DnD Kit, and TypeScript. Feature-rich, accessible, performant, and designed for real business needs.
- High Performance: Virtualized rendering for massive datasets (10k+ rows)
- Editable Cells: Radix UI-based editors (text, number, select, date, boolean, rating, textarea)
- Drag & Drop: Column and row reordering with DnD Kit
- Nested Rows: Expand/collapse hierarchical data
- Column Management: Resizing, hiding, pinning, and reordering columns
- Theming: Easy theming with Tailwind CSS and Radix states
- Accessibility: Full keyboard navigation and screen reader support
- TypeScript: Complete type safety with rich interfaces
- Backward Compatible: Drop-in replacement for existing column/data structures
npm install tanstack-react-table
# or
yarn add tanstack-react-table
# or
bun add tanstack-react-table
Peer dependencies:
react^18react-dom^18@tanstack/react-table^8
import React from "react";
import { TableComponent } from "tanstack-react-table";
import type { ColumnProps } from "tanstack-react-table";
const columns: ColumnProps[] = [
{
id: "name",
header: "Name",
type: "text",
width: 200,
},
{
id: "email",
header: "Email",
type: "email",
width: 250,
},
{
id: "age",
header: "Age",
type: "number",
width: 100,
},
];
const data = [
{ id: "1", name: "John Doe", email: "john@example.com", age: 30 },
{ id: "2", name: "Jane Smith", email: "jane@example.com", age: 25 },
];
function MyTable() {
return (
{
console.log("Event:", type, value);
}}
onEndReached={() => {}}
/>
);
}
Built-in Radix UI-based cell editors:
- text: Basic input with validation
- number: Arrow stepper
- email: Email input and mailto links
- textarea: Multi-line editing
- select: Dropdown menu with search
- date: Calendar picker
- boolean: Toggle switch
- rating: Star rating
- readonly: Display only
| Prop | Type | Description |
|---|---|---|
Id |
string |
Unique identifier for the column. |
Title |
string | ReactNode |
Display title of the column. |
Type |
string |
Optional data type of the column. |
Render |
({ row, onExpand, onDone }) => ReactNode |
Optional custom render function for the column cell. |
Fixed |
string | null |
Optional fixed position for the column (e.g., 'left' or 'right'). |
enableSorting |
boolean |
Enable sorting functionality for the column. |
enableResizing |
boolean |
Enable resizing functionality for the column. |
enableHiding |
boolean |
Enable hiding functionality for the column. |
enablePinning |
boolean |
Enable pinning functionality for the column. |
enableOrdering |
boolean |
Enable ordering functionality for the column. |
Width |
number |
Initial width of the column. |
MinWidth |
number |
Minimum width the column can be resized to. |
MaxWidth |
number |
Maximum width the column can be resized to. |
Footer |
() => ReactNode |
Optional custom footer renderer for the column. |
Header |
() => ReactNode |
Optional custom header renderer for the column. |
Efficient rendering for huge datasets:
<TableComponent dataSource={largeData} columns={columns} isVirtual={true} rowHeight={50} />
const nestedData = [
{
id: "1",
name: "Parent Row",
subRows: [
{ id: "1-1", name: "Child Row 1" },
{ id: "1-2", name: "Child Row 2" },
],
},
];
import { MyCustomCell } from "./MyCustomCell";
Use your own or built-in Tailwind themes, Radix states, or external theme libraries.
| Prop | Type | Description |
|---|---|---|
selectedItems |
Array<string> |
Selected items in the table. |
showSerialNumber |
boolean |
Show or hide the serial number column. |
showRowSelection |
boolean |
Show or hide the row selection column. |
columns |
Array<ColumnProps> |
Array of column properties. |
datasource |
Array<object> |
Array of data objects. |
emptyState |
ReactNode |
Empty state component. |
onEventUpdate |
({ type, value }) => void |
Callback function when the user makes a change to the table. |
rowKey |
string |
Key of the column to be used as the row key. |
expandable |
ExpandableProps |
Expandable props. |
onEndReached |
() => void |
Callback function to fetch the next page of data when the user reaches the end of the table. |
loading |
boolean |
Flag to indicate if the table is loading. |
isVirtual |
boolean |
Flag to indicate if the table is vitrual. |
rowHeight |
number |
Height of each row. |
options |
TableOptionProps |
Table options. |
theme |
LargeThemeConfig |
Custom theme for the table. |
tableId |
string |
Its used to get the table id. |
| Prop | Type | Description |
|---|---|---|
type |
string |
Type of expansion (e.g., 'accordion', 'row'). |
isExpandable |
boolean |
Determines if the row is expandable. |
expandEntireRowByClick |
boolean |
Optional: Expands the entire row upon click. |
expandedRowKeys |
Array<string> |
Optional: Keys of the rows that are expanded by default. |
expandedRowRender |
((row: Row<object>) => React.ReactNode) | null |
Optional custom renderer for expanded rows. |
| Prop | Type | Description |
|---|---|---|
enableSorting |
boolean |
Enables sorting functionality for the all columns. |
enableResizing |
boolean |
Enables resizing functionality for the all columns. |
enableHiding |
boolean |
Enables hiding functionality for the all columns. |
enablePinning |
boolean |
Enables pinning functionality for the all columns. |
enableOrdering |
boolean |
Enables ordering functionality for the all columns. |
enableRowOrdering |
boolean |
Enables row ordering functionality for the table. |
| Prop | Type | Description |
|---|---|---|
onRowUpdate |
({ rowId, changedValue }) => void |
Updates the data of the table. |
updateTableData |
({ type, value }) => void |
Updates the table data. |
onColumnValidate |
({ columnId }) => void |
Updates the validate of the column. |
onVisibilityChange |
(columnId, value) => void |
Updates the visibility of the column. |
onColumnDrag |
(fromId, toId) => void |
Updates the order of the columns. |
onRowDrag |
(fromId, toId) => void |
Updates the order of the rows. |
onPinColumn |
(columnId, value) => void |
Pins or unpins a column. |
onAllRowsSelected |
(value) => void |
Selects or deselects all rows. |
onRowSelect |
(rowId, value) => void |
Selects or deselects a specific row. |
onAllRowsExpand |
(value) => void |
Expands or collapses all rows. |
onRowExpand |
(rowId, value) => void |
Expands or collapses a specific row. |
resetColumnVisibility |
(value) => void |
Resets column visibility to the default state. |
getTableValues |
() => ReturnType<typeof useReactTable> |
Returns the current table values. |
getSelectedItems |
() => string[] |
Returns the selected row IDs. |
getExpandedItems |
() => string[] |
Returns the expanded row IDs. |
getHiddenColumns |
() => Record<string, boolean> |
Returns the current column visibility state. |
const handleEventUpdate = ({ type, value }) => {
switch (type) {
case "UPDATE_EVENTS.CELL_EDIT": /* ... */ break;
case "row-select": /* ... */ break;
case "column-resize": /* ... */ break;
// ...
}
};
- Use virtualization for datasets >1,000 rows
- Memoize event handlers
- Batch row updates
- Optimize custom renderers with
React.memo - Use stable
rowKey
Q: Table not rendering properly? A: Ensure all peer dependencies are installed and check console for TypeScript errors.
Q: Custom renderers causing performance issues?
A: Wrap custom components with React.memo and avoid creating new objects/functions in render.
Q: Virtualization not working?
A: Make sure isVirtual={true} and rowHeight is set to a consistent value.
Q: Column resizing not working?
A: Ensure enableResizing: true is set on column definitions and container has defined width.
# Install dependencies
bun install
# Start development server
bun run dev
# Build the library
bun run build
# Run tests
bun test
# Lint and fix code
bun run lint
bun run format
# Type checking
bun run typecheck
# Generate documentation
bun run docsWe welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feat/new-feature) - Follow coding standards (Biome)
- Add tests for new functionality
- Update documentation as needed
- Commit changes (
git commit -m "Add new feature") - Push to GitHub (
git push origin feat/new-feature) - Open a Pull Request
- Follow TypeScript best practices
- Maintain backward compatibility
- Add unit tests for new features
- Update README for API changes
- Use conventional commit messages
- Chrome 88+
- Firefox 85+
- Safari 14+
- Edge 88+
Check out our comprehensive examples in the /examples directory:
MIT License β see the LICENSE file for details.
Built with β€οΈ using:
- TanStack Table - Headless table utilities
- Radix UI - Low-level UI primitives
- DnD Kit - Drag and drop utilities
- Tailwind CSS - Utility-first CSS framework
Β© 2025 Aravinthan