Skip to content
Back to skills

Materialreacttable Mastery

ASecurity

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.

  • 28 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added February 7, 2026
developmenttypescriptgobashreactgitapibackend

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 14 files and shows the line behind each finding

Scanned February 12, 2026

npx -y skills add georgekhananaev/claude-skills-vault --skill materialreacttable-mastery --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Materialreacttable Mastery?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Materialreacttable Mastery
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/georgekhananaev-materialreacttable-mastery/badge)](https://www.skillsdirectory.com/skills/georgekhananaev-materialreacttable-mastery)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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 <MaterialReactTable table={table} />;
```

### 2. Column Definitions in useMemo

ALWAYS wrap columns in `useMemo` to prevent unnecessary re-renders.

```tsx
const columns = useMemo<MRT_ColumnDef<Person>[]>(() => [
  { 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 }) => (
      <Chip
        label={cell.getValue<string>()}
        color={cell.getValue() === 'Active' ? 'success' : 'default'}
      />
    ),
  },
  {
    accessorKey: 'salary',
    header: 'Salary',
    filterVariant: 'range-slider',
    Cell: ({ cell }) => cell.getValue<number>().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<MRT_SortingState>([]);
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 }) => (
    <Box sx={{ display: 'flex', gap: '1rem' }}>
      <Tooltip title="Edit">
        <IconButton onClick={() => table.setEditingRow(row)}>
          <EditIcon />
        </IconButton>
      </Tooltip>
      <Tooltip title="Delete">
        <IconButton color="error" onClick={() => handleDelete(row.original.id)}>
          <DeleteIcon />
        </IconButton>
      </Tooltip>
    </Box>
  ),
});
```

### 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}) => <Details />` |
| Tree data | `enableExpanding: true, getSubRows: (row) => row.children` |
| Server-side | `manualPagination: true, manualFiltering: true, manualSorting: true` |

## Customization

### Toolbar

```tsx
renderTopToolbar: ({ table }) => (
  <Box sx={{ display: 'flex', gap: 2, p: 2 }}>
    <MRT_GlobalFilterTextField table={table} />
    <ExportButton data={data} />
  </Box>
),
```

### 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<MRT_ColumnFiltersState>([]);
  const [globalFilter, setGlobalFilter] = useState('');
  const [sorting, setSorting] = useState<MRT_SortingState>([]);
  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 <MaterialReactTable table={table} />;
}
```

## 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

Files in this skill

  • SKILL.md10.2 KB
  • references/advanced_features.md19.2 KB
  • references/column_definitions.md26.3 KB
  • references/customization.md8.5 KB
  • references/editing_crud.md5.8 KB
  • references/filtering_sorting.md4.3 KB
  • references/pagination_virtualization.md4.5 KB
  • references/row_selection.md4.8 KB
  • references/state_management_apis.md24.3 KB
  • references/tree_data.md5 KB
  • references/version_compatibility.md20.5 KB
  • templates/BasicTable.tsx1.8 KB
  • templates/EditableTable.tsx5.5 KB
  • templates/ServerSideTable.tsx5.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.