Back in July I wrote the first post about AdaptTable.
The project was still v1, and the idea was fairly focused: one table engine that could sit behind the UI kit a React project already uses.
MUI project? Use the MUI adapter.
Mantine? Use Mantine.
Ant Design, Chakra, Radix, shadcn, Base UI, or your own Tailwind styles all sit on the same engine too.
That model is still there. The engine behind it has just grown a lot since then.
The core is at v2.9 now.
GitHub · Live demo · Getting started
The feature set got much bigger
The first release already covered the things I kept needing in application tables: sorting, filtering, pagination, URL state, saved views, column controls, server-side data, mobile layouts, selection, and row/card virtualization.
Since then I've added quite a bit on top of that.
Grouping now supports multiple levels and aggregates.
There is tree data, pivot tables, formula/computed columns, and sparklines.
The editing side grew a lot too.
AdaptTable now has keyboard cell navigation, rectangular range selection, clipboard copy/paste, cut, fill handle behavior, and edit history.
Editing can happen at cell level, row level, or as batched changes. There is validation, async validation, dirty-state tracking, and conflict handling for cases where live data changes while somebody is editing.
Rows have more control now as well:
- Row reordering
- Top and bottom row pinning
- Row and column spanning
- Full-width rows
- Custom row heights and styling
- Tree and nested structures
Export also moved beyond CSV and print, with XLSX and PDF support now available.
Keeping the feature API manageable
As the feature set grew, I wanted a basic table to stay basic.
A normal table can still look like this:
<DataTable
data={rows}
columns={columns}
rowKey={(row) => row.id}
/>
v2 introduced a feature composition API for optional behavior.
For example, row reordering can be added through its own entry point:
import { DataTable } from "@adapttable/mantine";
import { rowReorder } from "@adapttable/mantine/row-reorder";
<DataTable
data={rows}
columns={columns}
rowKey={(row) => row.id}
features={[
rowReorder(handleReorder)
]}
/>
Grouping, editing, virtualization, cell navigation, saved views, and other features follow the same direction.
There is also a public TableFeature API behind this. A feature can register its own editors, aggregators, commands, filters, menu items, panels, and other extensions through the same feature system.
That gives me a cleaner way to keep expanding AdaptTable without turning every new capability into another permanent special case inside DataTable.
Some of the heavier code is already separate
I also started splitting heavier capabilities into their own entry points instead of exporting everything from the main core package.
Today the core has separate entries for things like:
@adapttable/core/xlsx
@adapttable/core/pdf
@adapttable/core/formula
@adapttable/core/pivot
@adapttable/core/stream
@adapttable/core/sparkline
Those are outside the main core entry, so the application pays the bundle-size cost for those features only when it imports and uses them.
The adapters have feature-specific entry points too. Mantine, for example, exposes paths such as:
@adapttable/mantine/row-reorder
@adapttable/mantine/grouping
@adapttable/mantine/editing
@adapttable/mantine/virtualize
@adapttable/mantine/cell-navigation
v2 still keeps some optional feature implementations reachable from the main DataTable import graph, so the adapter side doesn't get the full bundle-size benefit from those entry points yet.
v3 will move those optional implementations out of the root import graph so applications only pay for the features they actually import and use.
The deprecated v2 APIs will be removed at the same time.
The server side changed a lot too
The original TableSource idea is still there: the table can work with local data or with data controlled by a backend.
That area has expanded quite a bit.
There is now a separate @adapttable/server package for parsing and validating AdaptTable query state on the server.
Pagination, sorting, filters, filter trees, grouping, and pivot state can use the same table query model on both sides instead of needing a second representation just for the backend.
Real-time updates are in now too.
AdaptTable can consume row patches coming through WebSocket or SSE flows instead of reloading the entire dataset whenever something changes.
The live-update work also connects with editing. A remote update can arrive while somebody is changing the same row locally, so those two parts of the table need to understand each other.
There is support for SSR, React Server Components, and streaming as well.
A lot of the work after v1 ended up happening around the data flow and lifecycle of the table, not only in the rendered grid.
Eight adapters, one engine
The public adapters today are:
- Mantine
- MUI
- Chakra UI
- Ant Design
- Radix Themes
- Base UI
- shadcn/ui
- unstyled/Tailwind
They all use the same underlying table state and feature logic while rendering with the components and conventions of their own UI stack.
A Mantine project gets Mantine components. An MUI project gets MUI components. A project with its own design system can use the unstyled path.
The core behavior stays shared across them.
Everything is still MIT licensed.
v3 is next
While working on v2, I kept running into one thing I want to fix properly in v3: too much of the engine is still tied to React.
A lot of what AdaptTable does has nothing inherently React-specific about it.
Sorting, filtering, grouping, pivots, formulas, query state, editing state, row models, and feature logic can all exist without React.
For v3 I'm moving that logic into framework-neutral engine modules, with React hooks and components living in a separate binding layer.
React will remain fully supported, but it won't define the architecture of the engine underneath it.
That also opens the door to Vue and Angular integrations later without rebuilding the same table logic for each framework.
v3 will also remove the deprecated v2 APIs and continue the bundle cleanup by moving optional feature implementations out of the root import graph.
I'm also working on optional AI capabilities for v3.
Top comments (0)