Skip to content
Kadal UI

Data grid 0.1 · TanStack Table v9 · shadcn/ui on Base UI · MIT

The data grid your power users keep asking for.

Sorting, faceted filters, grouping, 50,000 virtualized rows, inline editing, keyboard ranges and clipboard, saved views. Typed end to end. One command copies the source into your project, so the code is yours.

npx shadcn@latest add @kadal/data-grid

Live. Sort, filter, group, drag a column, double-click a cell, press ⌘C.

Every feature, documented →
Yuki Khanyuki.khan@mail.testChurnedTeamGrowthDirector$0.002174.6%Sep 2, 2023May 5, 2025, 10:52 PMnps-9Japan—
Mateo Rossimateo.rossi@corp.exampleInvitedFreePlatformPM$0.0016.2%Oct 21, 2024Jul 7, 2026, 9:33 PM—GermanyRenewal in Q1.
Aarav Sharmaaarav.sharma@example.comChurnedProSupportLead$0.00224.5%Feb 6, 2026May 4, 2026, 8:56 PM—France—
Vihaan Tanakavihaan.tanaka@corp.exampleChurnedProFinanceManager$0.00292.8%Oct 14, 2023Aug 27, 2024, 3:51 AM—IndiaRenewal in Q1.
Mia Menonmia.menon@example.comActiveFreeFinanceDirector$0.00127.8%May 19, 2024Jul 27, 2025, 2:01 PMnps-9Canada—
Mateo Nguyenmateo.nguyen@corp.exampleActiveEnterpriseDesignManager$2,449.003129.5%Feb 27, 2025Sep 15, 2026, 11:14 AMapacBrazilSpeaks at meetups.
Theo Silvatheo.silva@team.devActiveProResearchEngineer$36.00347.5%Feb 19, 2024May 29, 2024, 11:16 AM—Australia—
Theo Sharmatheo.sharma@example.comPausedTeamFinanceDirector$406.001432.6%Nov 9, 2023Feb 2, 2025, 6:06 PMapacCanada—
Diya Silvadiya.silva@corp.exampleActiveFreeDataDesigner$0.0014.7%Oct 29, 2025Jun 23, 2026, 7:48 AMchurn-riskeuCanadaAsked about invoices.
Saanvi Patelsaanvi.patel@corp.exampleActiveFreeDesignAnalyst$0.00143.4%Oct 23, 2026Oct 31, 2026, 5:04 AMvipBrazil—
0 of 400 row(s) selected.
Page 1 of 40

How it ships

Not a dependency. Your code.

Kadal UI is a shadcn registry. The command above copies twenty-one TypeScript files into components/ui/data-grid/, pulls the shadcn primitives it uses, and adds TanStack Table and TanStack Virtual to your package.json. From then on it is your component: rename a label, swap an icon, delete a feature, add a column kind. Updates arrive as a diff you review, not a version bump you hope for.

  • React 19, TypeScript 7, Tailwind v4
  • shadcn/ui on Base UI, the new default
  • TanStack Table v9: tree-shaken features, store-based state
  • Works with Next.js, Vite, Astro, Remix, TanStack Start
  • kadal-ui diff shows what changed upstream
  • MIT, no licence keys, no enterprise tier
what the command does
$ npx shadcn@latest add @kadal/data-grid
✔ Checking registry.
✔ Installing dependencies.
  @tanstack/react-table@^9.3.1 @tanstack/react-virtual@^3.14.26
  @dnd-kit/react@^0.5.3 lucide-react
✔ Created 34 files:
  src/components/ui/data-grid/data-grid.tsx
  src/components/ui/data-grid/use-data-grid.tsx
  src/components/ui/data-grid/data-grid-columns.tsx
  src/components/ui/data-grid/data-grid-filters.tsx
  …
  src/components/ui/button.tsx   src/components/ui/popover.tsx
  src/components/ui/select.tsx   src/components/ui/tooltip.tsx

Docs: https://ui.kadal.cc/docs/data-grid/

What you get

Everything a grid needs on day one. Each one a page in the docs.

columns.tsx
const col = createDataGridColumns<Order>()

export const columns = col.columns([
  col.select(),
  col.text("customer", { header: "Customer", editable: true }),
  col.enum("status", { options: STATUS, editable: true }),
  col.currency("total", { currency: "EUR" }),
  col.percent("margin"),
  col.date("placedAt", { header: "Placed" }),
  col.tags("labels"),
  col.actions(({ row }) => <OrderMenu order={row.original} />),
])

<DataGrid data={orders} columns={columns}
  onCellEdit={({ row, columnId, value }) => save(row.id, columnId, value)} />

Type safety

Columns that know your rows.

col.currency("total") only accepts a key of Order, including nested paths. Its format, validate and onEdit see a number. The kind picks the sort function, the filter UI, the editor, the aggregation and the export format, so most columns are one line and none of them need a global type augmentation. Under it all is TanStack Table v9's feature-typed API: every method on the table instance exists because its feature is registered.

How the types work

Built for the keyboard

Spreadsheet hands welcome.

Click a cell and it's focused. Drag or hold Shift and you have a range. Press ⌘C and the range lands in a spreadsheet as tab-separated text, formatted the way the grid shows it. Every action the mouse can take has a key, and a screen reader hears what changed.

All the shortcuts
↑ ↓ ← →
Move the focused cell
Shift + arrows
Extend the selection
Home / End
First / last column
⌘ Home / ⌘ End
First / last row
PageUp / PageDown
A screen at a time
Enter / F2
Edit the cell
Space
Select the row
⌘ A
Select every cell
⌘ C
Copy as tab-separated text
Esc
Clear the selection

Free, and funded by you

MIT for everyone. Sponsors keep the issues answered.

There is no paid tier of Kadal UI and there won't be one. Sponsorships pay for time on bugs, docs, new components and the features you ask for, and put your name or logo in the README and on this site. Companies can pay by invoice.

Add it to your project now.

Five minutes from install to a grid with your data. Questions go to Discussions or the Discord; bugs and ideas have templates.

npx shadcn@latest add @kadal/data-grid

Also from Kadal