Open-source project
icflorescu/mantine-datatable avatar
icflorescu/mantine-datatable

mantine-datatable: a dependency free data grid for Mantine

The table component for your Mantine data-rich applications, supporting asynchronous data loading, column sorting, custom cell data rendering, context menus, nesting, Gmail-style batch row selection, dark theme, and more.

1,261 stars103 forksTypeScriptMIT

At a glance

What is it?
Mantine DataTable is a TypeScript table component for applications built on Mantine, and it adds no runtime dependencies of its own while shipping the behaviours a real grid needs, asynchronous loading, shift range selection, sorting, nesting, row expansion, drag and drop and a dark theme that follows Mantine's colour scheme. Its versioning is tied to Mantine's own, so the version you install has to match.
Who is it for?
Adopt mantine-datatable if you build on Mantine and need a data grid with the interaction details already solved, especially shift range selection, asynchronous loading with a loading indicator, nested tables and RTL behaviour, and if you are willing to track its version alongside Mantine's. Do not adopt it if your table is a static list of a few columns, or if you want a headless table model that you render yourself.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 44 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A grid that adds nothing to your bundle

The pitch in the README is a set of adjectives, and the first two are the ones that matter. Mantine DataTable is described as a lightweight, dependency-free, dark-theme aware table component for Mantine UI data rich applications.

Dependency free is the interesting claim for a component that does drag and drop, context menus and animations. The README credits the specific pieces to specific contributors, and that list explains how. Column reordering, toggling and resizing are thanks to the work of Giovambattista Fazioli, who is also listed as a valuable Mantine DataTable contributor. Drag and drop support is implemented using @hello-pangea/dnd, thanks to the work of Mohd Ahmad. The comprehensive RTL support, where the context menu adjusts automatically to the Mantine DirectionProvider settings, is thanks to Reem Assaf.

So the claim is not that nothing third party is involved anywhere, it is that the table component itself pulls in no runtime dependencies of its own, and the pieces that are used are attributed openly. The README links a bundle size check on bundlephobia for the package, which is the kind of thing a library that cares about its footprint would point at.

The dark theme support is automatic rather than a prop, since the table adapts to the current Mantine colour scheme, and the same URL works for light and dark. For an application with a theme switch, that means one less thing to wire.

The package is MIT licensed and authored by Ionut-Cristian Florescu, the version in the manifest is 9.4.0, the default branch is main, the last push was on 2026-09-11, and the documentation site is at icflorescu.github.io/mantine-datatable with a comprehensive list of examples.

Version 9 tracks Mantine 9, and the old V6 build lives elsewhere

The compatibility note sits at the top of the README in bold, and it is the first thing to read.

Mantine DataTable V9.x is compatible with Mantine V9.x. And if you are looking for the old version that works with Mantine V6, the README points to a separate project, Mantine DataTable V6, with its own documentation site.

That is a clean way to handle the problem, which is that a component library built on top of another one cannot be versioned independently of it for long. When Mantine moved, the table had to move, and rather than keeping one package with a wide peer range and conditional code for every Mantine generation, the author split the old line into its own package and kept the current line moving with the current Mantine.

The cost of that decision is that a project on an older Mantine has to install a different package, and the two are not drop in replacements for each other. The benefit is that the current line has one target, one set of styles and one set of behaviours, which is what makes a component like this pleasant to extend.

For a team picking this up, the version question is therefore not optional. The manifest version is 9.4.0, and that is a DataTable for Mantine 9, not a general purpose table that happens to work with anything.

Asynchronous loading is the feature that changes the API

Most of the feature list is table furniture, and one item is not.

Asynchronous data loading means loading data from a remote API endpoint and showing a loading indicator while waiting for the response. That single capability changes what a table component has to be. It is no longer a component that receives an array and renders it, it is a component that owns a request, a pending state and an empty state, and the surrounding application no longer has to write the same loading spinner and error handling around every table.

The rest of the list is the set of interactions that a table needs once the data is there, and each one is documented with its own example page. Pagination splits large data sets into pages. Column sorting sorts data by one or more columns, so multi column sort is in scope rather than an add on. Custom cell data rendering lets a cell be rendered with your own components, which is what a status badge or an avatar column needs. Row context menu shows a menu on right click over a row, built to work with the Mantine context menu component. Row expansion expands a row to show additional details. Nesting nests tables to show hierarchical data.

Then the smaller ones. The table can be automatically scrollable or auto height. It supports AutoAnimate for animating row sorting, addition and removal. Columns can be reordered, toggled and resized. Rows can be dragged and dropped. And the context menu adjusts itself to the Mantine DirectionProvider, which is how the RTL support is implemented.

Additive batch rows selection is the one worth singling out, because it is the kind of behaviour that takes real effort to get right. It selects or deselects ranges of rows using the Shift key, in the Gmail style, so a click sets an anchor and a shift click extends the range. The word additive in the README means the selection adds to what is already selected rather than replacing it.

The quickstart is three steps and a peer dependency

The install section of the README is short enough to quote in full, which is a good sign for a component meant to be dropped into an existing application.

You create a new application with Mantine following the Mantine getting started guide, you make sure the clsx peer dependency is installed, and then you install the package:

bash
npm i mantine-datatable

or, with yarn:

bash
yarn add mantine-datatable

The peer dependency on clsx is the detail that matters. A component library that declares a peer dependency is telling you that it expects the host application to provide that package, which keeps the component out of your dependency tree and keeps the version under your control. For a component that prides itself on adding no dependencies, clsx is the one it asks you to bring, and it is the same small class name utility that the Mantine ecosystem already uses.

After that the README moves on to importing the necessary CSS files. The documentation site is where the current list of import statements is kept.

For a component with this many styles, the CSS is a real part of the API rather than an afterthought, and the package manifest shows that the styles are shipped as separate export paths, which is the part to look at next.

Two stylesheet entry points and a dual module export

The exports map in the manifest is the part of the packaging worth reading closely, because it tells you how the styles and the code are meant to be consumed.

json
"exports": {
  ".": {
    "import": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.mjs"
    },
    "require": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "./styles.css": "./dist/styles.css",
  "./styles.layer.css": "./dist/styles.layer.css"
}

The root export is split by module system, with an import condition pointing at an ES module build and a require condition pointing at a CommonJS build, and the type declarations shared by both. That is the arrangement that keeps a single package working in a bundler based application and in a server rendered one, without a second install.

The two stylesheet paths are the more interesting part. There is a plain styles.css and a styles.layer.css. The second name tells you the package also ships a CSS layer version, and the layer approach is how a component can slot its styles into the cascade in a defined order rather than relying on the order in which stylesheets happen to be imported. For an application that already fights with specificity, that is a meaningful option, and the fact that both are published means you can choose the one that fits your setup.

The published files are limited to the dist directory, the README and the LICENSE, and the manifest points main at ./dist/index.js, module at ./dist/index.mjs and types at ./dist/index.d.ts. The repository itself is a pnpm workspace, with a pnpm-workspace.yaml and a pnpm-lock.yaml at the root, a components/ directory, a package/ directory, an app/ directory for the documentation site, and a biome.json as the linter configuration, with next.config.js for the docs site.

Where a data grid component is the wrong choice

The limits are ordinary, and they are the kind you can work out from the feature list.

The first is scale of need. If your table shows a handful of rows with two columns and no interactions, a component with asynchronous loading, drag and drop, nesting and context menus is more than you need. The DataTable earns its place when the data is large, the rows are selectable, or the table is the focus of the screen, and in a project where a table is a supporting element, it is a dependency and a bundle for nothing.

The second is that the component is opinionated about behaviour. Gmail style shift selection, right click context menus and column resizing are all implemented, and if your application has its own interaction conventions, you are either accepting them or overriding them. That is a legitimate choice, but it is a choice, and it should be made deliberately.

The third is the version coupling, which is the constraint to plan around. The component is tied to a Mantine major version, and the old line lives in a separate package, so an application that upgrades Mantine has to upgrade this in step, and an application that cannot move yet is on a package that no longer receives work. Since the project has no GitHub releases, the npm version is the version record, and the CHANGELOG.md in the repository is the history.

One practical note for teams evaluating it. The README lists a set of organisations using the component, including Microsoft, Namecheap and kapa.ai, with a quote from each. That is adoption evidence rather than a technical claim, and the component itself is what you would be adopting, one table at a time, in your own application.

Editorial conclusion

Adopt mantine-datatable if you build on Mantine and need a data grid with the interaction details already solved, especially shift range selection, asynchronous loading with a loading indicator, nested tables and RTL behaviour, and if you are willing to track its version alongside Mantine's. Do not adopt it if your table is a static list of a few columns, or if you want a headless table model that you render yourself. Verify first that your Mantine major version matches the DataTable major version, that clsx is installed as the peer dependency the quickstart requires, and that the stylesheet entry point you import matches your bundler setup.

Frequently asked questions

How do I install mantine-datatable?

Create an application with Mantine, make sure the clsx peer dependency is installed, then run npm i mantine-datatable or yarn add mantine-datatable. The package version is 9.4.0 and it is MIT licensed with no runtime dependencies of its own.

Which version of Mantine does mantine-datatable work with?

Mantine DataTable V9.x is compatible with Mantine V9.x. The README points users who need the version that works with Mantine V6 to a separate project, Mantine DataTable V6, with its own documentation site.

Does mantine-datatable support loading data from an API?

Yes. Asynchronous data loading is a documented feature, where you load data from a remote API endpoint and the table shows a loading indicator while waiting for the response, alongside pagination, column sorting, custom cell rendering, row expansion, nesting and shift key range selection.

How are the styles imported from mantine-datatable?

The package exports two stylesheet entry points, ./styles.css and ./styles.layer.css, alongside the root module export which resolves to an ES module build for import and a CommonJS build for require. The README's quickstart section is where the import statements for the CSS files are described.

Official sources

  1. icflorescu/mantine-datatable on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/icflorescu-mantine-datatable.svg)](https://hysenlabs.com/projects/icflorescu-mantine-datatable)

Was this useful?