AdaptTable: Headless React data table with UI kit adapters

Description:

AdaptTable is a headless React data table with adapters for Mantine, MUI, Chakra UI, Ant Design, Radix Themes, Base UI, shadcn/ui, and unstyled markup.

The selected adapter controls the table’s visual layer, while the headless model keeps column definitions, data operations, and table state in the application.

Preview

adapttable-headless-react-data-table

Features

  • One table model works across eight UI kit adapters and a fully headless core.
  • Client-side arrays and server-side queries use the TableSource contract.
  • Desktop rows become mobile cards below the configured breakpoint.
  • Sorting, filters, removable filter chips, pagination, infinite scroll, and URL-synced state are built in.
  • Column show/hide, reorder, pinning, resizing, inline editing, selection, and bulk actions are available from the table model.
  • Grouping, aggregates, pivot and formula columns, and CSV/XLSX export are available for larger table tasks.
  • RTL and i18n utilities, dark mode mapping, keyboard navigation, and ARIA grid semantics are part of the adapter layer.
  • Optional virtualization, realtime row updates, row spanning, PDF export, and custom prop-getters extend the table.

How to use it

Install an adapter

The CLI checks the UI kit in package.json and scaffolds a starter table. Run it from your app directory.

npx @adapttable/cli init

Manual Mantine setup

For a direct Mantine setup, install the core package, the Mantine adapter, and Mantine’s peer packages.

Replace @adapttable/mantine with the adapter for the UI kit already used by the project. Add that kit’s peer packages from its existing application setup.

pnpm add @adapttable/core @adapttable/mantine @mantine/core @mantine/hooks

Add the UI kit provider

Mantine applications need the Mantine stylesheet and a root MantineProvider. Add the equivalent provider required by the selected kit before rendering a DataTable.

import "@mantine/core/styles.css";
import { MantineProvider } from "@mantine/core";
export function AppRoot() {
  return (
    <MantineProvider>
      <PeopleTable />
    </MantineProvider>
  );
}

Render a client-side table

useFrontendData creates a TableSource from an in-memory array. Client-side sorting reads the column configuration passed to useFrontendData and DataTable.

import {
  DataTable,
  useFrontendData,
  type ColumnDef,
} from "@adapttable/mantine";
interface Person {
  id: string;
  name: string;
  role: string;
  status: string;
  hiredAt: string;
}
const columns: ColumnDef<Person>[] = [
  {
    key: "name",
    header: "Name",
    accessor: (person) => person.name,
    sortable: true,
  },
  { key: "role", header: "Role", accessor: (person) => person.role },
  {
    key: "status",
    header: "Status",
    accessor: (person) => person.status,
    filter: { type: "select", options: "auto" },
  },
  {
    key: "hiredAt",
    header: "Hired",
    accessor: (person) => person.hiredAt,
    filter: "dateRange",
  },
];
export function PeopleTable({ rows }: { rows: Person[] }) {
  const source = useFrontendData({ data: rows, columns });
  return (
    <DataTable
      source={source}
      columns={columns}
      rowKey={(person) => person.id}
    />
  );
}

Connect server data through TableSource

For paged or infinite server data, use useQuerySource({ usePaginatedQuery }). Both source hooks return TableSource<T>. DataTable still receives source, columns, and rowKey through that interface.

Add table-level filters

Filters that are not columns belong in the filters array on DataTable. Column filters stay on their column definition. In the example, companies is the existing select-options array from the application.

<DataTable
  source={source}
  columns={columns}
  filters={[
    {
      key: "companyId",
      type: "select",
      label: "Company",
      options: companies,
    },
    { key: "budget", type: "numberRange" },
  ]}
  rowKey={(row) => row.id}
/>

Available packages

PackageRole
@adapttable/coreHeadless engine with hooks, state, prop-getters, and types.
@adapttable/mantineMantine adapter with a styled DataTable.
@adapttable/muiMaterial UI adapter.
@adapttable/chakraChakra UI adapter.
@adapttable/antdAnt Design adapter that drives antd’s high-level table.
@adapttable/radixRadix Themes adapter.
@adapttable/base-uiBase UI adapter built on @base-ui/react.
@adapttable/shadcnUnstyled adapter pre-wired with the shadcn preset.
@adapttable/unstyledSemantic HTML with class and data-* hooks for Tailwind or custom CSS.
@adapttable/i18nLocale presets for 17 languages and direction helpers.
@adapttable/clinpx @adapttable/cli init scaffolding command.

Alternatives and related resources