# Mantine DataTable > A fully-featured React data table/data grid component for Mantine UI, trusted by thousands of developers and companies around the world, including Microsoft. `mantine-datatable` is a lightweight, dependency-free, dark-theme aware table component for React applications built with Mantine (https://mantine.dev), supporting asynchronous data loading, pagination, sorting, Gmail-style batch row selection, custom cell rendering, column grouping, dragging, toggling, resizing and pinning, row expansion, nested tables, context menus, RTL layouts and more. Key facts: - Mantine DataTable V9.x is compatible with Mantine V9.x (the major version follows Mantine’s; use `mantine-datatable@8` with Mantine 8, `mantine-datatable@7` with Mantine 7). Peer dependencies are `@mantine/core`, `@mantine/hooks`, `clsx`, `react` and `react-dom` (React 19+). It has no other dependencies. - Import `mantine-datatable/styles.layer.css` (or `mantine-datatable/styles.css`) **after** the Mantine core styles. When using the `styles.layer.css` files, declare `@layer mantine, mantine-datatable;` in your own CSS so Mantine core styles are applied first; otherwise the table may look broken (missing borders, wrong spacing, misplaced pinned columns). - The package entry point is marked `'use client'`. Since `DataTable` props usually include functions (`render`, `onRowClick` etc.), render it from a client component (a file with the `'use client'` directive) in React Server Components environments such as the Next.js app router. - `DataTable` is generic: the record type is inferred from `records`. When declaring columns outside the component, type them as `DataTableColumn[]`. - `records` is the array of rows to display; `columns` is an array of objects, each with an `accessor` (a record key, or a dot-notation path like `department.company.name`). A column without `render` displays the accessor value; when `title` is omitted, it is generated by "humanizing" the accessor (`firstName` → "First name"). An accessor doesn’t have to match a record key if the column has a `render` function. Use `groups` instead of `columns` to group columns under shared headers. - Each record needs a unique key, read from its `id` property by default. Use `idAccessor` (a property name, a dot-notation path or a function `(record) => key`) when your records have a different unique identifier; the same key is used to compare records for selection and row expansion. - The component does **not** paginate, sort or filter data for you. Pagination (`page`, `onPageChange`, `totalRecords`, `recordsPerPage`, with a 1-based `page`) expects `records` to contain only the current page. Sorting (`sortStatus: { columnAccessor, direction }`, `onSortStatusChange`, `sortable: true` on columns) only renders the indicators and reports changes: sort the records yourself. Filtering is done by passing a `filter` node to a column and filtering the records yourself. - Selection is controlled: pass `selectedRecords` and `onSelectedRecordsChange` (optionally `isRecordSelectable`, `selectionTrigger: 'checkbox' | 'cell'`). Shift-click selects ranges, Gmail-style. - Set `fetching` to show a loader overlay while loading data asynchronously; an empty `records` array shows a customizable empty state (`noRecordsText`, `emptyState`, `noRecordsIcon`). - The table is vertically scrollable with a sticky header only when it has a restricted height (`height`, `maxHeight`, or a height-restricted parent); otherwise it grows with its content. It is always horizontally scrollable if its content is wider than its container. - Column dragging, toggling and interactive pinning (`draggable`, `toggleable`, `pinnable` on columns) require a `storeColumnsKey` on the table and the `useDataTableColumns({ key, columns })` hook called with the same `key`: pass the returned `effectiveColumns` to `columns`. Their state is persisted in `localStorage`. Column resizing (`resizable: true`) also works without them, but then widths are not persisted. - Row expansion is configured with the `rowExpansion` property (`content`, `trigger`, `allowMultiple`, controlled `expanded` state); nested tables are built by rendering another `DataTable` (with `noHeader`) inside the expansion content. - Styling: use Mantine table props (`withTableBorder`, `withColumnBorders`, `striped`, `highlightOnHover`, `borderRadius`, `shadow`, `verticalSpacing`, `fz` etc.), color props (`c`, `backgroundColor`, `borderColor`, `rowBorderColor`, `stripedColor`, `highlightOnHoverColor`, `selectionColor`), `className`/`style`/`classNames`/`styles`, per-row `rowClassName`, `rowStyle`, `rowColor`, `rowBackgroundColor`, and per-column `cellsClassName`, `cellsStyle`. `createStyles` (Mantine V6) is not available. - RTL layouts are supported automatically through Mantine’s `DirectionProvider`. The complete documentation, including all code examples and type definitions, is available as a single file at https://icflorescu.github.io/mantine-datatable/llms-full.txt ## Docs - [Getting started](https://icflorescu.github.io/mantine-datatable/getting-started/): Learn how to get started with Mantine DataTable - [Styling](https://icflorescu.github.io/mantine-datatable/styling/): Learn how styling works in Mantine DataTable and how to make sure your styles are applied in the correct order - [Type definitions](https://icflorescu.github.io/mantine-datatable/type-definitions/): Mantine DataTable is written in TypeScript and its properties are documented with JSDoc annotations ## Examples - [Basic usage](https://icflorescu.github.io/mantine-datatable/examples/basic-usage/): basic usage of Mantine DataTable - [Basic table properties](https://icflorescu.github.io/mantine-datatable/examples/basic-table-properties/): how to set the basic Mantine DataTable properties - [Overriding the default styles](https://icflorescu.github.io/mantine-datatable/examples/overriding-the-default-styles/): how to override the default Mantine DataTable styles - [Column properties and styling](https://icflorescu.github.io/mantine-datatable/examples/column-properties-and-styling/): setting Mantine DataTable column properties and customizing their styling - [Column grouping](https://icflorescu.github.io/mantine-datatable/examples/column-grouping/): group multiple Mantine DataTable columns under a shared header - [Default column properties](https://icflorescu.github.io/mantine-datatable/examples/default-column-properties/): using default column properties with Mantine DataTable - [Default column render](https://icflorescu.github.io/mantine-datatable/examples/default-column-render/): using a default column render function with Mantine DataTable - [Row styling](https://icflorescu.github.io/mantine-datatable/examples/row-styling/): styling Mantine DataTable rows based on their data - [Non-standard record IDs](https://icflorescu.github.io/mantine-datatable/examples/non-standard-record-ids/): using non-standard record IDs with Mantine DataTable - [Scrollable vs. auto-height](https://icflorescu.github.io/mantine-datatable/examples/scrollable-vs-auto-height/): how to make Mantine DataTable vertically scrollable - [Scrolling a row into view](https://icflorescu.github.io/mantine-datatable/examples/scrolling-a-row-into-view/): how to scroll a Mantine DataTable row into view - [Empty state](https://icflorescu.github.io/mantine-datatable/examples/empty-state/): Mantine DataTable shows a customizable empty state indicator when its records array is empty - [Pagination](https://icflorescu.github.io/mantine-datatable/examples/pagination/): using paged data with Mantine DataTable - [Sorting](https://icflorescu.github.io/mantine-datatable/examples/sorting/): sorting data with Mantine DataTable - [Column dragging and toggling](https://icflorescu.github.io/mantine-datatable/examples/column-dragging-and-toggling/): dragging & toggling Mantine DataTable columns - [Row dragging](https://icflorescu.github.io/mantine-datatable/examples/row-dragging/): dragging Mantine DataTable rows - [Column resizing](https://icflorescu.github.io/mantine-datatable/examples/column-resizing/): resizing Mantine DataTable columns - [Infinite scrolling](https://icflorescu.github.io/mantine-datatable/examples/infinite-scrolling/): how to implement infinite scrolling with Mantine DataTable - [Searching and filtering](https://icflorescu.github.io/mantine-datatable/examples/searching-and-filtering/): searching and filtering data with Mantine DataTable - [Records selection](https://icflorescu.github.io/mantine-datatable/examples/records-selection/): how to enable multiple records selection with Mantine DataTable - [Handling row clicks](https://icflorescu.github.io/mantine-datatable/examples/handling-row-clicks/): handling row click events on Mantine DataTable - [Handling cell clicks](https://icflorescu.github.io/mantine-datatable/examples/handling-cell-clicks/): handling cell click events on Mantine DataTable - [Using with Mantine ContextMenu](https://icflorescu.github.io/mantine-datatable/examples/using-with-mantine-contextmenu/): how to use Mantine DataTable with Mantine ContextMenu - [Expanding rows](https://icflorescu.github.io/mantine-datatable/examples/expanding-rows/): the row expansion feature of Mantine DataTable - [Nested tables](https://icflorescu.github.io/mantine-datatable/examples/nested-tables/): how to implement nested tables with Mantine DataTable - [Nested tables with async data loading](https://icflorescu.github.io/mantine-datatable/examples/nested-tables-with-async-data-loading/): how to implement nested tables with async data loading using Mantine DataTable - [Nested tables with async data loading and sorting](https://icflorescu.github.io/mantine-datatable/examples/nested-tables-with-async-data-loading-and-sorting/): how to implement nested tables with async data loading and sorting using Mantine DataTable - [Row actions cell](https://icflorescu.github.io/mantine-datatable/examples/row-actions-cell/): how to implement a row actions cell on Mantine DataTable - [Pinning the last column](https://icflorescu.github.io/mantine-datatable/examples/pinning-the-last-column/): how to pin the last column on Mantine DataTable - [Pinning the first column](https://icflorescu.github.io/mantine-datatable/examples/pinning-the-first-column/): how to pin the first column on Mantine DataTable - [Pinning arbitrary columns](https://icflorescu.github.io/mantine-datatable/examples/pinning-arbitrary-columns/): how to pin arbitrary columns on Mantine DataTable - [RTL support](https://icflorescu.github.io/mantine-datatable/examples/rtl-support/): Mantine DataTable supports right-to-left (RTL) languages such as Arabic, Hebrew and Persian - [Links or buttons inside clickable rows or cells](https://icflorescu.github.io/mantine-datatable/examples/links-or-buttons-inside-clickable-rows-or-cells/): how to add links or buttons inside Mantine DataTable clickable rows or cells - [Disabling text selection](https://icflorescu.github.io/mantine-datatable/examples/disabling-text-selection/): disabling text selection on Mantine DataTable - [Asynchronous data loading](https://icflorescu.github.io/mantine-datatable/examples/asynchronous-data-loading/): loading data asynchronously with Mantine DataTable and customizing the loader - [Custom row or cell attributes](https://icflorescu.github.io/mantine-datatable/examples/custom-row-or-cell-attributes/): how to add custom attributes to Mantine DataTable rows or cells - [Using bodyRef with AutoAnimate](https://icflorescu.github.io/mantine-datatable/examples/using-with-auto-animate/): how to use the Mantine DataTable bodyRef property with AutoAnimate - [Complex usage scenario](https://icflorescu.github.io/mantine-datatable/examples/complex-usage-scenario/): a complex usage scenario for Mantine DataTable with TanStack Query data loading, sorting, pagination, custom cell rendering, row selection and more ## Optional - [Mantine V6 support](https://icflorescu.github.io/mantine-datatable/mantine-v6-support/): Mantine DataTable V7+ requires Mantine V7 or newer; if you're still using Mantine V6, please check the old documentation website - [Contribute and support](https://icflorescu.github.io/mantine-datatable/contribute-and-support/): Support Mantine DataTable by sponsoring or hiring its author, starring the repo, reporting issues, suggesting ideas or opening pull requests - [Hire the author](https://icflorescu.github.io/mantine-datatable/hire-the-author/): Hire Ionut-Cristian Florescu, the author of Mantine DataTable, a hands-on fractional CTO and product builder with 25+ years of experience - [Changelog](https://github.com/icflorescu/mantine-datatable/blob/main/CHANGELOG.md): Notable changes in each Mantine DataTable version - [Source code](https://github.com/icflorescu/mantine-datatable): GitHub repository - [Mantine ContextMenu](https://icflorescu.github.io/mantine-contextmenu/): Context menu component for Mantine, by the same author (its own LLM-friendly docs: https://icflorescu.github.io/mantine-contextmenu/llms.txt)