Quick Start

Build your first data table in a few minutes

How it fits together

shadcntable is a set of composable pieces on top of TanStack Table v9:

  • useDataTable creates the table instance and owns its state.
  • DataTable renders the rows. DataTableToolbar and DataTablePagination sit around it, and all three take the same table.
  • Column definitions describe the data, and meta turns on labels and filters.

Everything is copied into your project, so you can change any piece.

1. Define your columns

Create a column helper for your row type. Keep columns outside the component so it stays the same between renders.

tsx
import { DataTableColumnHeader } from '@/components/shadcntable/data-table-column-header'
import { createDataTableColumnHelper } from '@/components/shadcntable/lib/features'

type User = {
  id: string
  name: string
  email: string
  role: 'admin' | 'editor' | 'viewer'
}

const columnHelper = createDataTableColumnHelper<User>()

const columns = columnHelper.columns([
  columnHelper.accessor('name', {
    header: ({ column }) => <DataTableColumnHeader column={column} />,
    meta: { label: 'Name' },
  }),
  columnHelper.accessor('email', {
    header: ({ column }) => <DataTableColumnHeader column={column} />,
    meta: { label: 'Email' },
  }),
  columnHelper.accessor('role', {
    header: ({ column }) => <DataTableColumnHeader column={column} />,
    meta: { label: 'Role' },
  }),
])

DataTableColumnHeader takes its title from meta.label. It gives the column a menu to sort and hide it.

2. Render the table

tsx
'use client'

import { DataTable } from '@/components/shadcntable/data-table'
import { DataTablePagination } from '@/components/shadcntable/data-table-pagination'
import { DataTableToolbar } from '@/components/shadcntable/data-table-toolbar'
import { useDataTable } from '@/components/shadcntable/use-data-table'

export function UsersTable({ users }: { users: User[] }) {
  const table = useDataTable({ columns, data: users })

  return (
    <div className='space-y-4'>
      <DataTableToolbar table={table} />
      <DataTable table={table} />
      <DataTablePagination table={table} />
    </div>
  )
}

You now have sorting, global search, column visibility and pagination.

3. Add filters

Give a column a meta.filter and its header gets a filter button:

tsx
columnHelper.accessor('role', {
  header: ({ column }) => <DataTableColumnHeader column={column} />,
  meta: {
    label: 'Role',
    filter: {
      variant: 'multiSelect',
      options: [
        { label: 'Admin', value: 'admin' },
        { label: 'Editor', value: 'editor' },
        { label: 'Viewer', value: 'viewer' },
      ],
    },
  },
})

The variants are text, select, multiSelect, numberRange, dateRange and custom. See filters.

4. Add row selection

Put the selection column first. The pagination bar then shows how many rows are selected.

tsx
import { createSelectionColumn } from '@/components/shadcntable/data-table-selection-column'

const columns = columnHelper.columns([
  createSelectionColumn<User>(),
  // ...your columns
])

Read the selection with table.getSelectedRowModel().rows. To own the state yourself, pass state.rowSelection and onRowSelectionChange to useDataTable.

Next steps