TanStack
Getting Started

Plugin workspace

The Plugins destination arranges open plugins in a workspace you can rearrange: panes side by side, stacked on top of each other, or grouped as tabs. Up to eighteen plugins can be open at once.

Opening a plugin

The Plugins strip lists the plugins that are not open. Once a plugin has a pane, its entry leaves the strip — the pane's own tab is where you select and close it, so there is only ever one control for it.

  • Click an entry to open it beside the others, sharing the space equally.
  • Drag an entry down into the workspace to choose where it lands, using the same zones as below. Dropping onto an empty workspace gives it the whole area.

The strip folds itself away when everything is open, and comes back on its own the moment a plugin closes and returns to it.

Arranging panes

Each pane has a tab above it. Click a tab to bring that pane to the front of its group; drag it to rearrange:

Drop it onResult
the left or right quarter of a panethe pane splits into a column, and the tab takes the new side
the top or bottom quarter of a panethe pane splits into a row
the middle of a panethe tab joins that pane as a stacked tab
another pane's tab barthe tab moves into that group, at the position you drop it

A highlight shows where the pane will land before you let go, and the tab you are carrying follows the cursor so it is clear which pane is moving.

Dropping on a tab bar always means "put it in this group" rather than splitting the top edge, so the two gestures never compete for the same few pixels.

When a pane is too small to split

The devtools panel is short, so splitting a small pane would leave both halves unreadable. When there is not enough room, the same drop becomes a stacked tab instead of being refused. Stacking costs no space, so every plugin stays usable in a short panel. The highlight tells you which is about to happen.

At the default panel height a vertical split has no room at all, so drops on a top or bottom edge stack instead. Drag the panel taller first if you want rows.

Resizing

Drag the gutter between two panes. One pane grows by exactly what the other loses, and neither can shrink past a readable minimum.

Keyboard

Everything above works without a pointer. This matters in a detached picture-in-picture window, where the pointer gestures are deliberately turned off (the same way the panel's own resize handle is) but the keyboard still works.

Moving a pane — focus a tab, then:

KeyAction
Enter or Spacepick the pane up, or drop it if already held
Arrow keyschoose where it goes — a neighbouring pane, or a side of its own pane to split
Escapeput it back

Resizing — focus a gutter, then:

KeyAction
Arrow keysmove the gutter
Shift + Arrowmove it in larger steps
Home / Endpush it as far as it will go

Picking a pane up and putting it down is announced to screen readers.

What persists

The arrangement is saved to localStorage and restored on reload, including which tab is selected in each group and the size of every pane.

If a plugin is no longer registered, it is dropped from the saved arrangement and the panes around it close up. If the saved arrangement cannot be read at all, the devtools recover by reopening whichever plugins it can identify as a single group, rather than refusing to open.

State saved by an older version, which recorded only which plugins were open, reopens as one group in that order. This happens once and is then saved in the new form.

Notes for plugin authors

Panes are never re-parented. A plugin's mount node stays a child of the same element for as long as the plugin is open, whatever you do to the layout, so an <iframe> will not reload and a <canvas> will not lose its context when the user drags panes around.

destroy is called when the plugin closes, once, and before its mount node is removed — so the node is still there if you need to clean up inside it. Moving, splitting, resizing and switching destinations do not call it. Navigating to Marketplace, SEO or Settings leaves your pane mounted and hidden.

render is called again when the theme or the panel's open state changes, as documented in plugin lifecycle.