---
name: materialreacttable-mastery
description: Material React Table V3 expert skill. Use when building feature-rich data tables w/ MUI styling, server-side ops, CRUD editing, virtualization, or complex filtering/sorting.
author: George Khananaev
---
# Material React Table Mastery
Build production-grade data tables w/ MRT V3 (TanStack Table V8 + MUI).
## When to Use
- Building data tables with MUI styling
- Server-side pagination/filtering/sorting
- CRUD editing (inline, modal, cell, table)
- Large dataset virtualization (10k+ rows)
- Complex filtering (date range, multi-select, faceted)
- Migrating between MRT versions (V1→V2→V3)
- MUI v7 compatibility issues
## Triggers
- `/mrt-init` - Initialize MRT setup w/ dependencies
- `/mrt-column` - Generate typed column definitions
- `/mrt-crud` - Add CRUD editing capabilities
- `/mrt-server` - Configure server-side pagination/filtering/sorting
- `/mrt-migrate` - Migrate between MRT versions (V1→V2→V3)
- `/mrt-state` - State management, persistence, controlled state
- `/mrt-export` - Data export (CSV, Excel, PDF)
- `/mrt-a11y` - Accessibility & keyboard navigation setup
## Reference Files
| Category | Reference | When to Load |
|----------|-----------|--------------|
| Columns | `references/column_definitions.md` | Accessors, formatters, grouping, aggregation, V1→V2→V3 migration |
| Filtering | `references/filtering_sorting.md` | Filter variants, global search, faceted |
| Pagination | `references/pagination_virtualization.md` | Server-side, infinite scroll, virtualization |
| Editing | `references/editing_crud.md` | Inline, modal, row, cell, validation |
| Selection | `references/row_selection.md` | Multi-select, actions, bulk ops |
| Tree | `references/tree_data.md` | Hierarchical data, expand/collapse |
| Custom | `references/customization.md` | Toolbar, styling, mrtTheme, localization, z-index |
| State | `references/state_management_apis.md` | Table/row/cell APIs, state persistence, events |
| Advanced | `references/advanced_features.md` | A11y, export, drag & drop, click-to-copy |
| Versions | `references/version_compatibility.md` | Version matrix, migrations, prop renames |
## Core Tenets
### 1. TanStack Table Foundation
MRT wraps TanStack Table V8. Use `useMaterialReactTable` hook for full control.
```tsx
import { useMaterialReactTable, MaterialReactTable } from 'material-react-table';
const table = useMaterialReactTable({
columns,
data,
enableColumnFilters: true,
enableGlobalFilter: true,
enablePagination: true,
});
return ;
```
### 2. Column Definitions in useMemo
ALWAYS wrap columns in `useMemo` to prevent unnecessary re-renders.
```tsx
const columns = useMemo[]>(() => [
{ accessorKey: 'name', header: 'Name', size: 200 },
{
accessorFn: (row) => `${row.firstName} ${row.lastName}`,
id: 'fullName',
header: 'Full Name',
},
{
accessorKey: 'status',
header: 'Status',
filterVariant: 'select',
filterSelectOptions: ['Active', 'Inactive', 'Pending'],
Cell: ({ cell }) => (
()}
color={cell.getValue() === 'Active' ? 'success' : 'default'}
/>
),
},
{
accessorKey: 'salary',
header: 'Salary',
filterVariant: 'range-slider',
Cell: ({ cell }) => cell.getValue().toLocaleString('en-US', {
style: 'currency', currency: 'USD',
}),
aggregationFn: 'sum',
AggregatedCell: ({ cell }) => `Total: ${cell.getValue()}`,
},
], []);
```
### 3. Server-Side Operations
For datasets > 100 rows, use server-side pagination/filtering/sorting.
```tsx
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
const [sorting, setSorting] = useState([]);
const [globalFilter, setGlobalFilter] = useState('');
const { data, isLoading } = useQuery({
queryKey: ['users', pagination, sorting, globalFilter],
queryFn: () => fetchUsers({ pagination, sorting, globalFilter }),
});
const table = useMaterialReactTable({
columns,
data: data?.rows ?? [],
rowCount: data?.totalCount ?? 0,
manualPagination: true,
manualSorting: true,
manualFiltering: true,
state: { pagination, sorting, globalFilter, isLoading },
onPaginationChange: setPagination,
onSortingChange: setSorting,
onGlobalFilterChange: setGlobalFilter,
});
```
### 4. CRUD Editing
Support inline, modal, cell, or table editing modes.
```tsx
const table = useMaterialReactTable({
columns,
data,
enableEditing: true,
editDisplayMode: 'row', // 'modal' | 'cell' | 'table'
onEditingRowSave: async ({ values, row, table }) => {
await updateUser(row.original.id, values);
table.setEditingRow(null);
},
renderRowActions: ({ row, table }) => (
table.setEditingRow(row)}>
handleDelete(row.original.id)}>
),
});
```
### 5. Virtualization for Large Data
Enable row virtualization for 10,000+ rows.
```tsx
const table = useMaterialReactTable({
columns,
data: largeDataset,
enableRowVirtualization: true,
rowVirtualizerOptions: { overscan: 5 },
muiTableBodyRowProps: { sx: { height: 53 } }, // Fixed height for perf
});
```
## Decision Tree
```
Dataset size?
├─ < 100 rows → Client-side (default)
├─ 100-10,000 rows → Server-side pagination
└─ > 10,000 rows → Virtualization + server-side
```
## Common Configurations
| Use Case | Configuration |
|----------|---------------|
| Basic display | `enableColumnFilters: false, enablePagination: false` |
| Editable | `enableEditing: true, editDisplayMode: 'row'` |
| Selection | `enableRowSelection: true, enableMultiRowSelection: true` |
| Expandable | `enableExpanding: true, renderDetailPanel: ({row}) => ` |
| Tree data | `enableExpanding: true, getSubRows: (row) => row.children` |
| Server-side | `manualPagination: true, manualFiltering: true, manualSorting: true` |
## Customization
### Toolbar
```tsx
renderTopToolbar: ({ table }) => (
),
```
### Row Styling
```tsx
muiTableBodyRowProps: ({ row }) => ({
sx: { backgroundColor: row.original.isHighlighted ? 'action.hover' : undefined },
}),
```
### Localization
```tsx
import { MRT_Localization_ES } from 'material-react-table/locales/es';
localization: MRT_Localization_ES,
```
## Filter Variants
| Type | Variant | Use Case |
|------|---------|----------|
| Text | `'text'` (default) | Free text search |
| Select | `'select'` | Enum/status fields |
| Multi-select | `'multi-select'` | Tags, categories |
| Range | `'range'` | Numeric ranges |
| Range Slider | `'range-slider'` | Price, age |
| Date | `'date'` | Date fields |
| Date Range | `'date-range'` | Date ranges |
| Autocomplete | `'autocomplete'` | Large option sets |
| Checkbox | `'checkbox'` | Boolean fields |
## React Query Integration
```tsx
function UsersTable() {
const [columnFilters, setColumnFilters] = useState([]);
const [globalFilter, setGlobalFilter] = useState('');
const [sorting, setSorting] = useState([]);
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
const { data, isLoading, isError } = useQuery({
queryKey: ['users', columnFilters, globalFilter, pagination, sorting],
queryFn: () => fetchUsers({ columnFilters, globalFilter, pagination, sorting }),
placeholderData: keepPreviousData,
});
const table = useMaterialReactTable({
columns,
data: data?.users ?? [],
rowCount: data?.meta?.totalRowCount ?? 0,
manualFiltering: true,
manualPagination: true,
manualSorting: true,
state: { columnFilters, globalFilter, isLoading, pagination, showAlertBanner: isError, sorting },
onColumnFiltersChange: setColumnFilters,
onGlobalFilterChange: setGlobalFilter,
onPaginationChange: setPagination,
onSortingChange: setSorting,
});
return ;
}
```
## Anti-Patterns
| Don't | Do |
|-------|-----|
| Recreate columns on every render | Wrap in `useMemo` |
| Fetch all data for server-side | Implement backend pagination |
| Skip virtualization for 10k+ rows | Enable `enableRowVirtualization` |
| Custom filter UI for common cases | Use built-in `filterVariant` |
| Ignore loading states | Use `isLoading` state prop |
| Inline column definitions | Define outside component or `useMemo` |
| Hardcode table text | Use `localization` prop |
## Dependencies
```bash
npm install material-react-table @mui/material @mui/x-date-pickers @mui/icons-material @emotion/react @emotion/styled @tanstack/react-query
```
## Version Compatibility
| MRT | MUI | React | Notes |
|-----|-----|-------|-------|
| V3 | 6+ (v7 experimental) | 18+ | Current - keyboard nav default |
| V2 | 5.11+ | 17+ | Maintenance |
| V1 | 5.0+ | 17+ | Deprecated |
**MUI v7 Status**: ⚠️ Not officially supported yet. Known issues: dark mode broken, TypeScript errors. Use `--legacy-peer-deps` if required. Track [GitHub #1401](https://github.com/KevinVandy/material-react-table/issues/1401).
**Key V2→V3 changes**: `text` → `label` in select options, keyboard nav enabled by default.
## Checklist
- [ ] Columns wrapped in `useMemo`
- [ ] Proper accessors (`accessorKey` | `accessorFn` + `id`)
- [ ] `filterVariant` set per column type
- [ ] Server-side for > 100 rows
- [ ] Virtualization for > 10k rows
- [ ] `isLoading` state connected
- [ ] Error states handled (`showAlertBanner`)
- [ ] Validation in `onEditingRowSave`
- [ ] Row actions labeled for a11y
- [ ] `LocalizationProvider` if using date filters
- [ ] Version-appropriate props (V1→V2→V3 renames)
- [ ] z-index handled if table in modal/drawer