# Devtools

TanStack Table provides framework-specific devtools adapters that plug into the [TanStack Devtools](https://tanstack.com/devtools) multi-panel UI.

The table devtools let you inspect registered table instances, switch between multiple tables, and inspect features, state, options, rows, and columns in real time.

> [!NOTE]
> By default, the framework adapters only include the live devtools in development mode. In production builds they export no-op implementations unless you opt into the `/production` entrypoints.

## Installation

Install the TanStack Devtools host package and the Table adapter for your framework.

> [!IMPORTANT]
> While TanStack Table v9 is in beta, the table devtools adapters must be installed with the `@beta` tag. Installing without the tag resolves to the old v8 devtools, which have a completely different API.

```sh
npm install @tanstack/angular-devtools @tanstack/angular-table-devtools@beta
```

Lit, Svelte, and vanilla do not currently ship dedicated table devtools adapters.

## The Required `key` Table Option

The devtools identify each table by the `key` table option. Registration requires it: if you register a table without a `key`, the devtools log an error (`Missing table key. Add a 'key' option to your table to use devtools.`) and skip the table entirely.

```ts
const table = useTable({
  key: 'users-table', // needed for devtools, omit if you don't want to use the devtools
  features,
  columns,
  data,
})
```

The `key` is also the label shown in the devtools panel selector, so give each table a unique, descriptive key.

## Setup Pattern

The recommended setup has three parts:

1. Give each table a unique `key` option
2. Mount `TanStackDevtools` at the app root with `tableDevtoolsPlugin()`
3. Register each table with `useTanStackTableDevtools(table)` (or `injectTanStackTableDevtools` in Angular) immediately after creating it

If you register multiple tables, the Table panel shows a selector so you can switch between them.

## Setup

Provide the devtools host once in your application config, rendering the table panel from `@tanstack/angular-table-devtools`:

```ts
// app.config.ts
import { isDevMode } from '@angular/core'
import { provideTanStackDevtools } from '@tanstack/angular-devtools/provider'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
  providers: [
    isDevMode()
      ? provideTanStackDevtools(() => ({
          plugins: [
            {
              name: 'TanStack Table',
              render: () =>
                import('@tanstack/angular-table-devtools').then((m) =>
                  m.TableDevtoolsPanel(),
                ),
            },
          ],
        }))
      : [],
  ],
}
```

Then register each table with `injectTanStackTableDevtools` in an injection context (such as a component constructor):

```ts
import { Component } from '@angular/core'
import { injectTable } from '@tanstack/angular-table'
import { injectTanStackTableDevtools } from '@tanstack/angular-table-devtools'

@Component({
  // ...
})
export class App {
  constructor() {
    injectTanStackTableDevtools(() => ({
      table: this.table,
    }))
  }

  readonly table = injectTable(() => ({
    key: 'users-table', // needed for devtools
    // ...
  }))
}
```

See the [Angular basic example](./framework/angular/examples/basic-inject-table) or the [Angular row-selection example](./framework/angular/examples/row-selection).

## Disabling Registration

Each registration function accepts an `enabled` option if you want to conditionally register a table:

```ts
injectTanStackTableDevtools(() => ({
  table: this.table,
  enabled: () => false,
}))
```

## Production Builds

If you need the live devtools in production, import from the `/production` entrypoint for your framework package:

```ts
import { injectTanStackTableDevtools } from '@tanstack/angular-table-devtools/production'
```
