Table

An accessible table primitive built on React Aria — semantic markup, keyboard navigation, row selection and sortable columns. Pair it with TanStack Table for sorting, filtering and pagination logic, as in the example below.

Total Results

48 customers

PurchaseStatusActions
John Clarkson
Delivery failedNov 19, 2026$1.804
Aspen Lubin
Delivery waitingNov 14, 2026$2.506
Michael Ekstrom
Delivery failedMar 15, 2026$1.241
Kianna Vaccaro
ShippedNov 02, 2026$1.893
Livia Saris
Delivery waitingMar 22, 2026$265
Jaydon Aminoff
ShippedJun 23, 2026$3.373
Maria Lubin
ShippedJul 17, 2026$224
Ann Press
ShippedSep 25, 2026$1.228

Installation

You can add this table component using our CLI or manually:

  1. 1
    Install the following dependencies
    npm install react-aria-components @tanstack/react-table
  2. 2
    Create atable.tsxfile and paste the following into it.

    table.tsx

    // components/base/table/table.tsx"use client"; import { Table as AriaTable, TableHeader as AriaTableHeader, Column as AriaColumn, TableBody as AriaTableBody, Row as AriaRow, Cell as AriaCell,} from "react-aria-components";import { cx } from "@/utils/cx"; // Built on React Aria for semantic markup, keyboard navigation, row// selection and sortable columns. Pair with @tanstack/react-table for// sorting / filtering / pagination logic (see the example above). export function Table({ className, ...props }) { return ( <div className="w-full overflow-x-auto"> <AriaTable className={cx("w-full border-collapse text-left", className)} {...props} /> </div> );} // Styling is applied via scoped CSS on '.bui-table' (see styles/globals.css):// thead bg-neutral-100, border-y// th px-3 py-2.5 text-body-medium text-text-tertiary// td px-3 py-2.5 text-body-medium text-neutral-800// tbody tr border-b border-neutral-200// so the collection components can be re-exported without wrappers. export function TableColumn({ className, ...props }) { return <AriaColumn className={cx(className)} {...props} />;} export function TableRow({ className, ...props }) { return <AriaRow className={cx(className)} {...props} />;} export function TableCell({ className, ...props }) { return <AriaCell className={cx(className)} {...props} />;} export { AriaTableHeader as TableHeader, AriaTableBody as TableBody };
  3. 3
    Update the import paths to match your project setup.

Sizes

The table comes in 2 sizes: md (normal) and sm (compact, with tighter padding and smaller avatars). Switch between them by changing the size prop on the Table component — try the Normal / Compact toggle in the preview above.

<Table size="md" aria-label="Customers"> {/* rest of the table components */}</Table>

Table of Contents

This guide shows how to use TanStack Table — the headless engine for rows, columns, sorting, filtering and selection — together with the Table primitive to build your own data table. We'll cover the following topics:

  • Basic table with the Table primitive
  • Row selection
  • Sorting
  • Filtering & search
  • Pagination
  • Reusable components