# data-table-filters registry

> Open-source React data table with faceted filters, sorting, infinite scroll, and virtualization. Distributed as shadcn registry blocks you install into your own repo — not as an npm dependency, so there is no library to wrap and nothing to eject from.

Works on either shadcn library: the CLI default, Base UI (`npx shadcn@latest init -d`), or Radix (`npx shadcn@latest init -b radix -p lyra`). CI installs into both and typechecks them on every registry change and nightly.

Install any block with `npx shadcn@latest add @data-table-filters/<block>`, or by URL with `npx shadcn@latest add https://data-table.openstatus.dev/r/<block>.json`. Blocks may be combined in a single command; the CLI installs each block's registry dependencies automatically, so listing a dependency explicitly is redundant but harmless.

## Blocks

| Block | Install | URL | What it adds | Use when |
| --- | --- | --- | --- | --- |
| `data-table` | `@data-table-filters/data-table` | https://data-table.openstatus.dev/r/data-table.json | Data table with search, checkbox, slider, date range filters, sorting, infinite scroll, virtualization, and in-memory state management. | Always install first. Core engine: table, the 4 filter types (input, checkbox, slider, timerange), infinite scroll, virtualization, and the in-memory store adapter. |
| `data-table-filter-command` | `@data-table-filters/data-table-filter-command` | https://data-table.openstatus.dev/r/data-table-filter-command.json | Command palette for power-user filter input with history and keyboard shortcuts. | The table needs a cmd+k command palette for power-user filter input, with query history and keyboard shortcuts. |
| `data-table-cell` | `@data-table-filters/data-table-cell` | https://data-table.openstatus.dev/r/data-table-cell.json | Cell renderer system with 12 types: text, code, badge, boolean, star, number, status-code, level-indicator, timestamp, heatmap, bar, and gauge. | Columns need formatted rendering: badges, bars, heatmaps, status codes, log levels, booleans, timestamps. |
| `data-table-sheet` | `@data-table-filters/data-table-sheet` | https://data-table.openstatus.dev/r/data-table-sheet.json | Row detail side panel with cell renderers, keyboard navigation, and copy-to-clipboard. | Clicking a row should open a detail side panel. Auto-installs the cell renderers. |
| `data-table-nuqs` | `@data-table-filters/data-table-nuqs` | https://data-table.openstatus.dev/r/data-table-nuqs.json | URL-based state management adapter using nuqs for shareable, bookmarkable filter state. | Filter state must live in the URL so links are shareable and bookmarkable. The default choice for Next.js apps. |
| `data-table-zustand` | `@data-table-filters/data-table-zustand` | https://data-table.openstatus.dev/r/data-table-zustand.json | Client-side state management adapter using zustand for app-level filter persistence. | Filter state must live in client app state instead of the URL, or the app already uses zustand. |
| `data-table-schema` | `@data-table-filters/data-table-schema` | https://data-table.openstatus.dev/r/data-table-schema.json | Declarative table definitions with col.* factories, presets, and generators for columns, filters, and sheet fields. | One declarative definition should drive columns, filters, sheet fields, and sorting. Required by the drizzle, mcp, and ai-filters blocks. Also carries the shared filter-semantics module that the SQL, in-memory, and TanStack engines all read from. |
| `data-table-drizzle` | `@data-table-filters/data-table-drizzle` | https://data-table.openstatus.dev/r/data-table-drizzle.json | Server-side filtering, faceted search, cursor pagination, and sorting helpers for Drizzle ORM. | Rows live in a SQL database and must be filtered server-side. This is the block for large tables: SQL-side filtering, faceted counts, cursor pagination, and sorting. If you installed this block before the filter-semantics fix, re-run `shadcn add` for both data-table-drizzle and data-table-schema: earlier copies compiled a numeric checkbox with exactly two values selected to `BETWEEN`, silently matching everything in between. |
| `data-table-query` | `@data-table-filters/data-table-query` | https://data-table.openstatus.dev/r/data-table-query.json | React Query infinite query integration with a pluggable transport (base URL, headers, credentials, response parsing), cursor and offset pagination strategies, and faceted search helpers. | The table fetches pages from an API endpoint — React Query infinite-query wiring with SuperJSON and facet merging. |
| `data-table-filter-command-ai` | `@data-table-filters/data-table-filter-command-ai` | https://data-table.openstatus.dev/r/data-table-filter-command-ai.json | AI-powered command palette that translates natural language queries into structured table filters. Provider-agnostic — works with any LLM via Vercel AI SDK. | Users should be able to filter in natural language ("errors in the last hour") on top of the command palette. |
| `data-table-mcp` | `@data-table-filters/data-table-mcp` | https://data-table.openstatus.dev/r/data-table-mcp.json | Expose your data table as an MCP endpoint for AI agents. Auto-generates tool schema from BYOS field definitions. Stateless, serverless-compatible. | The table should be queryable by AI agents over MCP, using the same schema the UI uses. |
| `data-table-actions` | `@data-table-filters/data-table-actions` | https://data-table.openstatus.dev/r/data-table-actions.json | Row, bulk, and filter-scoped actions declared next to their Drizzle handlers and rendered from JSON: the list endpoint advertises what can be done to each row, the UI renders buttons, one POST applies it in a transaction. | Users need to DO something to rows — replay, acknowledge, delete — not just read them. Actions are declared once next to their Drizzle handler; the list endpoint advertises them and stamps each row with what applies, the UI renders row menus, a bulk bar, and an apply-to-all-matching menu from that JSON, and one POST runs the handler in a transaction. Requires the drizzle block. |
| `data-table-remote` | `@data-table-filters/data-table-remote` | https://data-table.openstatus.dev/r/data-table-remote.json | A headless data table that renders from an API endpoint: point it at a table manifest and a list endpoint and it derives columns, filters, sheet fields, row identity and capability-aware degradation with no per-column code. | The table should render from an API endpoint rather than from per-column code — you own the data and publish only a schema. Serve a table manifest (schema, primaryKey, capabilities, actions) with createTableManifestHandler, then point <DataTableRemote /> at it: columns, filters, sheet fields and row identity are all derived, and anything the endpoint says it cannot compute (facets, counts, chart, backwards paging) degrades instead of rendering empty. |
| `data-table-chart` | `@data-table-filters/data-table-chart` | https://data-table.openstatus.dev/r/data-table-chart.json | Stacked timeline bar chart above the table: one bar per time bucket, one series per level, drag to select a range and zoom the table's time filter to it. Ships the bucketing helper that turns rows into chart data with the same semantics as the Drizzle handler. | The table should show a stacked timeline above the rows — one bar per time bucket, one series per level — with drag-to-zoom on the time filter. The endpoint has to return meta.chartData: the Drizzle handler does; for rows in memory, bucketChartData from lib/data-table/chart-data builds it with the same semantics. Pass the series (keys, labels, colours) or let the chart infer them from the data. |
| `data-table-example-infinite` | `@data-table-filters/data-table-example-infinite` | https://data-table.openstatus.dev/r/data-table-example-infinite.json | A complete /example route to see the table running before wiring your own data: a table schema, a mock API that filters, computes facets and cursor-paginates in memory with the same semantics as the Drizzle handler, and the infinite table with a timeline chart, URL state, command palette, row sheet and a hand-written timing phases column. Delete app/example when you have your own. | You want to see a complete table running before wiring your own data. Ships a /example route: a table schema, a mock API that filters, computes facets and cursor-paginates in memory with the same semantics as the Drizzle handler, and the infinite table with URL state, command palette and row sheet. Installs every block it needs. Delete app/example when you have your own table. |

## Recipes

### Working example route (see it running first)

When: A new or empty app, and the goal is a table on screen before any data is wired up.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-example-infinite
```

Installs app/example: a page and layout with the providers, a table schema, a mock API route, and the infinite table with a timeline chart, URL state, command palette and row sheet. Run the dev server and open /example. Change the columns in app/example/table-schema.ts; replace app/example/api/route.ts with createDrizzleHandler when the rows live in Postgres.

### Large table (server-side, 100k+ rows)

When: Rows live in Postgres/MySQL/SQLite and cannot be shipped to the client.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-schema @data-table-filters/data-table-cell @data-table-filters/data-table-sheet @data-table-filters/data-table-drizzle @data-table-filters/data-table-query @data-table-filters/data-table-nuqs
```

Define the table once with createTableSchema, pass it to createDrizzleHandler in a route handler, and to createDataTableQueryOptions on the client. Filtering, faceted counts, sorting, and cursor pagination all run in SQL; the client only ever holds the pages it rendered.

### Client-side table (data already in memory)

When: A few thousand rows at most, already fetched or imported.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-cell @data-table-filters/data-table-sheet
```

Use the memory adapter via useMemoryAdapter. No API route and no schema block required.

### Zero-config table from raw JSON

When: The shape of the data is not known ahead of time.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-schema
```

Render <DataTableAuto data={json} />, or call inferSchemaFromJSON + createTableSchema.fromJSON to get columns, filters, and sheet fields inferred from the data itself.

### Table pointed at an API endpoint

When: The data and its endpoint are owned elsewhere, and the app should render whatever the endpoint describes without per-column code.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-schema @data-table-filters/data-table-query @data-table-filters/data-table-nuqs @data-table-filters/data-table-remote
```

Serve a manifest with createTableManifest + createTableManifestHandler on the endpoint that owns the data, then render <DataTableRemote manifestEndpoint="/api/logs/schema" />. Pass initialManifest (a build-time snapshot or a server prefetch) to avoid a round trip before the first paint. Use the transport option for another origin, auth headers, or a plain-JSON API.

### Table with row actions (server-side)

When: Rows live in Postgres and users need to act on them — replay, acknowledge, discard — from the table.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-schema @data-table-filters/data-table-drizzle @data-table-filters/data-table-query @data-table-filters/data-table-nuqs @data-table-filters/data-table-actions
```

Declare actions with createActionHandler next to createDrizzleHandler, sharing its filters and columnMapping. The list route adds meta.actions and per-row _actions; a POST route calls actionHandler.execute. On the client, wrap the table in DataTableActionsProvider and drop in createActionsColumn and DataTableActionsBar.

### AI-queryable table

When: Agents or end users should query the table in natural language.

```bash
npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-schema @data-table-filters/data-table-filter-command @data-table-filters/data-table-filter-command-ai @data-table-filters/data-table-mcp
```

The schema drives all three surfaces: UI filters, the AI filter parser, and the MCP tool definition. Define columns once.

## Block dependencies

- `data-table` pulls in: no other blocks
- `data-table-filter-command` pulls in: `data-table`
- `data-table-cell` pulls in: `data-table`
- `data-table-sheet` pulls in: `data-table`, `data-table-cell`
- `data-table-nuqs` pulls in: `data-table`
- `data-table-zustand` pulls in: `data-table`
- `data-table-schema` pulls in: `data-table`, `data-table-cell`, `data-table-sheet`, `data-table-filter-command`
- `data-table-drizzle` pulls in: `data-table`, `data-table-schema`
- `data-table-query` pulls in: `data-table`
- `data-table-filter-command-ai` pulls in: `data-table`, `data-table-filter-command`, `data-table-schema`
- `data-table-mcp` pulls in: `data-table`
- `data-table-actions` pulls in: `data-table`, `data-table-drizzle`, `data-table-query`
- `data-table-remote` pulls in: `data-table`, `data-table-schema`, `data-table-query`, `data-table-nuqs`
- `data-table-chart` pulls in: `data-table`
- `data-table-example-infinite` pulls in: `data-table`, `data-table-schema`, `data-table-query`, `data-table-nuqs`, `data-table-sheet`, `data-table-cell`, `data-table-filter-command`, `data-table-chart`

## More

- These docs as an MCP server: https://data-table.openstatus.dev/api/mcp
- Docs index for agents: https://data-table.openstatus.dev/llms.txt
- Full documentation in one file: https://data-table.openstatus.dev/llms-full.txt
- Any docs page as raw markdown: append `.md` (e.g. https://data-table.openstatus.dev/docs/quick-start.md)
