# data-table-filters > 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. - Stack: React 19+, TanStack Table v8, Tailwind CSS v4, shadcn/ui. Next.js App Router is first-class; the blocks work in any React app. - 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. - Starting from nothing? `pnpm dlx shadcn@latest init @data-table-filters/data-table-example-infinite --name logs-viewer --template next -p lyra` creates a Next.js app, initializes shadcn on Base UI, and installs a working example route with every block it needs; run the dev server and open http://localhost:3000/example. Add `-b radix` before `-p lyra` for Radix. - Install with `npx shadcn@latest add @data-table-filters/` — the registry is in the shadcn directory, so no components.json entry is needed; the block URL `https://data-table.openstatus.dev/r/.json` works too. The shadcn CLI resolves block dependencies, rewrites `@/` import paths to match components.json, and injects the required CSS variables. - Built for large tables: filtering, faceted counts, sorting, and cursor pagination all execute in SQL, and rows are virtualized, so table size is bounded by the database rather than the browser. - One `createTableSchema` definition drives the columns, the filter controls, the row detail sheet, the server-side query handler, the natural-language filter parser, and the MCP tool schema. ## Recipes Install the blocks for the goal, in the order listed. ### 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 , 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 . 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. ## Registry blocks - [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. **Use when:** 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](https://data-table.openstatus.dev/r/data-table-filter-command.json): Command palette for power-user filter input with history and keyboard shortcuts. **Use when:** The table needs a cmd+k command palette for power-user filter input, with query history and keyboard shortcuts. - [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. **Use when:** Columns need formatted rendering: badges, bars, heatmaps, status codes, log levels, booleans, timestamps. - [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. **Use when:** Clicking a row should open a detail side panel. Auto-installs the cell renderers. - [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. **Use when:** Filter state must live in the URL so links are shareable and bookmarkable. The default choice for Next.js apps. - [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. **Use when:** Filter state must live in client app state instead of the URL, or the app already uses zustand. - [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. **Use when:** 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](https://data-table.openstatus.dev/r/data-table-drizzle.json): Server-side filtering, faceted search, cursor pagination, and sorting helpers for Drizzle ORM. **Use when:** 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](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. **Use when:** The table fetches pages from an API endpoint — React Query infinite-query wiring with SuperJSON and facet merging. - [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. **Use when:** Users should be able to filter in natural language ("errors in the last hour") on top of the command palette. - [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. **Use when:** The table should be queryable by AI agents over MCP, using the same schema the UI uses. - [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. **Use when:** 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](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. **Use when:** 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 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](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. **Use when:** 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](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. **Use when:** 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. ## Docs - [Introduction](https://data-table.openstatus.dev/docs/introduction.md): Overview of the data-table system architecture and layers - [Quick Start](https://data-table.openstatus.dev/docs/quick-start.md): Start from scratch with one shadcn command and a working table at /example, or add the blocks to a project you already have: one prerequisite, one install command, one paste - [Table Schema](https://data-table.openstatus.dev/docs/table-schema.md): Type-safe builder for defining your entire table in one place - [State Management](https://data-table.openstatus.dev/docs/state-management.md): Pluggable adapter pattern for filter state — nuqs (URL), Zustand, memory, or custom - [UI Components](https://data-table.openstatus.dev/docs/ui-components.md): Pre-built filter controls, command palette, infinite scroll table, and row detail drawer - [Data Fetching](https://data-table.openstatus.dev/docs/data-fetching.md): TanStack React Query integration with useInfiniteQuery, query options factory, and server prefetching - [Data Layer](https://data-table.openstatus.dev/docs/data-layer.md): Server-side concepts for filtering, faceted search, cursor pagination, and chart data - [Drizzle ORM](https://data-table.openstatus.dev/docs/drizzle-orm.md): Step-by-step walkthrough for building a server-side data table with Drizzle ORM and PostgreSQL - [Features](https://data-table.openstatus.dev/docs/features.md): Timeline chart, live mode, and keyboard shortcuts - [AI Filters](https://data-table.openstatus.dev/docs/ai-filters.md): Translate natural language queries into structured table filters using any LLM - [Builder](https://data-table.openstatus.dev/docs/builder.md): Visually build a table schema from JSON data or CSV - [Full Example](https://data-table.openstatus.dev/docs/full-example.md): Complete end-to-end example combining table schema, state management, and components - [Debugging](https://data-table.openstatus.dev/docs/debugging.md): Type errors right after install from an older copy of the blocks, and performance debugging with react-scan and TanStack Query devtools - [MCP Server](https://data-table.openstatus.dev/docs/mcp.md): Expose your data table as a queryable MCP endpoint for AI agents - [For AI Agents](https://data-table.openstatus.dev/docs/agents.md): Machine-readable docs, install recipes, and agent rules for building data tables with Claude Code, Cursor, and other coding agents - [Row Actions](https://data-table.openstatus.dev/docs/actions.md): Declare actions next to their Drizzle handlers; the table renders row menus and a bulk bar from server metadata - [Headless Tables](https://data-table.openstatus.dev/docs/headless.md): Point the table at an API endpoint and let it render whatever that endpoint describes — schema, capabilities, row identity, and actions - [Upgrading from shadcn/ui Table](https://data-table.openstatus.dev/docs/migrating-from-shadcn.md): How to upgrade a basic shadcn data table with Linear-style faceted filters, URL state, infinite scroll, and server-side SQL execution ## Optional - [MCP server](https://data-table.openstatus.dev/api/mcp): these docs as tools — `search_docs`, `get_doc`, `list_blocks`, `get_install_plan`. Streamable HTTP, no auth - [llms-full.txt](https://data-table.openstatus.dev/llms-full.txt): every documentation page inlined in one file - [Registry index](https://data-table.openstatus.dev/r/index.md): block catalog with install commands and dependencies - [Registry manifest](https://data-table.openstatus.dev/r/registry.json): machine-readable shadcn registry - [Claude Code plugin](https://github.com/openstatushq/data-table-filters): `/plugin marketplace add openstatushq/data-table-filters` then `/plugin install data-table-filters@openstatus` - [Agent skill](https://github.com/openstatushq/data-table-filters): `npx skills add https://github.com/openstatushq/data-table-filters --skill data-table-filters`