
Tanstack Devtools
- 86 installs
- 14 repo stars
- Updated March 2, 2026
- oakoss/agent-skills
Helps with ai & agent building tasks during AI-assisted development.
About
tanstack-devtools is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- tanstack-devtools
- AI & Agent Building
- AI-coding skill
Tanstack Devtools by the numbers
- 86 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #4,993 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oakoss/agent-skills --skill tanstack-devtoolsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 86 |
|---|---|
| repo stars | ★ 14 |
| Last updated | March 2, 2026 |
| Repository | oakoss/agent-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
TanStack DevTools
Overview
TanStack DevTools provides debugging panels for inspecting Query cache state, Router route trees, and Form field state in React applications. There are two approaches: standalone devtools per library (ReactQueryDevtools, TanStackRouterDevtools) and the unified TanStack Devtools panel that combines all libraries into a single interface with plugin architecture.
When to use: Setting up devtools for TanStack libraries, debugging query cache behavior, inspecting route matching, monitoring form field state, or combining multiple TanStack devtools into one panel.
When NOT to use: Production debugging (devtools are tree-shaken in production by default), non-React frameworks without adapter support, or custom state management unrelated to TанStack libraries.
Quick Reference
| Pattern | API | Key Points |
|---|---|---|
| Query devtools (floating) | <ReactQueryDevtools /> | Auto-connects to nearest QueryClient |
| Query devtools (embedded) | <ReactQueryDevtoolsPanel /> | Embed in custom layout |
| Router devtools (floating) | <TanStackRouterDevtools /> | Place in root route component |
| Router devtools (embedded) | <TanStackRouterDevtoolsPanel /> | Requires router prop outside provider |
| Form devtools | <ReactFormDevtoolsPanel /> | Plugin for unified devtools |
| Unified devtools | <TanStackDevtools plugins={[...]} /> | Single panel for all TanStack libraries |
| Vite plugin | devtools() in vite config | Source injection, enhanced logs, production removal |
| Production devtools | ReactQueryDevtoolsInProd | Opt-in for production environments |
| Lazy loading | React.lazy(() => import(...)) | Reduce bundle size in development |
| Open hotkey | config={{ openHotkey: ['Shift', 'D'] }} | Keyboard shortcut for unified panel |
Unified Devtools Config
| Option | Type | Purpose |
|---|---|---|
position | `'top-left' \ | 'top-right' \ |
panelLocation | `'top' \ | 'bottom'` |
theme | `'dark' \ | 'light'` |
defaultOpen | boolean | Open panel on load |
hideUntilHover | boolean | Hide trigger until hover |
openHotkey | KeyboardKey[] | Toggle panel shortcut |
inspectHotkey | KeyboardKey[] | Source inspector shortcut |
requireUrlFlag | boolean | Only activate with URL parameter |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
| Importing devtools in production bundle | Standalone devtools auto-tree-shake; use React.lazy for code-splitting |
Passing router prop when inside RouterProvider | Omit router prop; devtools auto-detect context |
Using ReactQueryDevtools position for panel placement | buttonPosition controls logo position; position controls panel edge |
| Mixing standalone and unified devtools | Choose one approach; both rendering causes duplicate panels |
| Rendering devtools outside QueryClientProvider | Place ReactQueryDevtools inside provider or pass client prop |
Using TanStackRouterDevtools outside route tree | Place in root route component or pass router prop explicitly |
| Forgetting Vite plugin for unified devtools | Add devtools() from @tanstack/devtools-vite to vite config |
| Using unified devtools without framework adapter | Install both @tanstack/react-devtools and library-specific plugin packages |
Delegation
- Devtools setup review: Use
Taskagent to verify correct placement and configuration - Bundle size analysis: Use
Exploreagent to check devtools are tree-shaken in production - Code review: Delegate to
code-revieweragent
If the tanstack-query skill is available, delegate query-specific debugging patterns to it.Otherwise, recommend: npx skills add oakoss/agent-skills --skill tanstack-query>
If the tanstack-router skill is available, delegate route debugging patterns to it.Otherwise, recommend: npx skills add oakoss/agent-skills --skill tanstack-router>
If the tanstack-form skill is available, delegate form state management and validation patterns to it.References
- Query devtools setup, modes, and options
- Router devtools setup, route inspection, and options
- Form devtools and unified devtools patterns
Form Devtools and Unified Panel
Form Devtools
TanStack Form devtools are available through the unified TanStack Devtools panel as a plugin. There is no standalone floating component for form devtools.
Installation
pnpm add @tanstack/react-devtools @tanstack/react-form-devtoolsBoth the unified devtools adapter and the form-specific plugin package are required.
Basic Setup
import { TanStackDevtools } from '@tanstack/react-devtools';
import { ReactFormDevtoolsPanel } from '@tanstack/react-form-devtools';
function App() {
return (
<>
<YourApp />
<TanStackDevtools
plugins={[
{
id: 'tanstack-form',
name: 'TanStack Form',
render: <ReactFormDevtoolsPanel />,
defaultOpen: true,
},
]}
/>
</>
);
}Unified TanStack Devtools
The unified devtools panel combines Query, Router, and Form devtools into a single interface. It replaces multiple floating panels with one centralized tool.
Installation
pnpm add @tanstack/react-devtools @tanstack/react-query-devtools @tanstack/react-router-devtools @tanstack/react-form-devtoolsInstall the core adapter and each library-specific plugin you need.
Full Setup with All Plugins
import { TanStackDevtools } from '@tanstack/react-devtools';
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
import { ReactFormDevtoolsPanel } from '@tanstack/react-form-devtools';
function App() {
return (
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
<TanStackDevtools
plugins={[
{
id: 'tanstack-query',
name: 'TanStack Query',
render: <ReactQueryDevtoolsPanel />,
defaultOpen: true,
},
{
id: 'tanstack-router',
name: 'TanStack Router',
render: <TanStackRouterDevtoolsPanel router={router} />,
},
{
id: 'tanstack-form',
name: 'TanStack Form',
render: <ReactFormDevtoolsPanel />,
},
]}
/>
</QueryClientProvider>
);
}Config Options
<TanStackDevtools
config={{
position: 'bottom-right',
panelLocation: 'bottom',
theme: 'dark',
defaultOpen: false,
hideUntilHover: false,
openHotkey: ['Shift', 'D'],
inspectHotkey: ['Shift', 'I'],
requireUrlFlag: false,
urlFlag: 'devtools',
}}
eventBusConfig={{
debug: false,
connectToServerBus: true,
port: 42069,
}}
plugins={[...]}
/>Config Reference
| Option | Type | Default | Description |
|---|---|---|---|
position | `'top-left' \ | 'top-right' \ | 'bottom-left' \ |
panelLocation | `'top' \ | 'bottom'` | 'bottom' |
theme | `'dark' \ | 'light'` | 'dark' |
defaultOpen | boolean | false | Open on initial load |
hideUntilHover | boolean | false | Hide trigger until hover |
openHotkey | KeyboardKey[] | — | Panel toggle shortcut |
inspectHotkey | KeyboardKey[] | — | Source inspector shortcut |
requireUrlFlag | boolean | false | Require URL param to activate |
urlFlag | string | 'devtools' | URL param name when requireUrlFlag is true |
triggerImage | string | — | Custom trigger button image URL |
Event Bus Config
| Option | Type | Default | Description |
|---|---|---|---|
debug | boolean | false | Enable event bus debug logging |
connectToServerBus | boolean | false | Connect to external devtools server |
port | number | 42069 | Server communication port |
Vite Plugin
The @tanstack/devtools-vite plugin enhances the development experience with source injection, enhanced logging, and automatic production removal.
import { defineConfig } from 'vite';
import { devtools } from '@tanstack/devtools-vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
devtools({
removeDevtoolsOnBuild: true,
logging: true,
enhancedLogs: { enabled: true },
injectSource: {
enabled: true,
ignore: {
files: [/node_modules/, /\.test\.(ts|tsx)$/],
components: [/^Internal/, /^Private/],
},
},
eventBusConfig: {
enabled: true,
port: 42069,
},
}),
react(),
],
});Vite Plugin Options
| Option | Type | Description |
|---|---|---|
removeDevtoolsOnBuild | boolean | Strip devtools from production builds |
logging | boolean | Console logging for plugin actions |
enhancedLogs.enabled | boolean | Add file/line info to console logs |
injectSource.enabled | boolean | Add data-tsd-source attributes to JSX |
injectSource.ignore | { files, components } | Patterns to exclude from source injection |
eventBusConfig.enabled | boolean | Enable event bus server |
eventBusConfig.port | number | Event bus server port |
Next.js Considerations
When using unified devtools in Next.js, wrap the devtools component in a client component to avoid server-side rendering errors:
'use client';
import { TanStackDevtools } from '@tanstack/react-devtools';
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
export function DevtoolsProvider() {
return (
<TanStackDevtools
plugins={[
{
id: 'tanstack-query',
name: 'TanStack Query',
render: <ReactQueryDevtoolsPanel />,
},
]}
/>
);
}Then render <DevtoolsProvider /> in your root layout.
Query Devtools
Installation
pnpm add @tanstack/react-query-devtoolsThe package is a separate install from @tanstack/react-query. It is automatically tree-shaken from production builds when imported from the default entry point.
Floating Mode
Floating mode renders a toggle button fixed to the screen corner. Panel state persists in localStorage across reloads.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}Floating Mode Props
| Prop | Type | Default | Description |
|---|---|---|---|
initialIsOpen | boolean | false | Whether devtools panel starts open |
buttonPosition | `'top-left' \ | 'top-right' \ | 'bottom-left' \ |
position | `'top' \ | 'bottom' \ | 'left' \ |
client | QueryClient | nearest context | Custom QueryClient instance |
errorTypes | { name: string; initializer: (query: Query) => TError }[] | [] | Predefined errors to trigger from UI |
styleNonce | string | — | CSP nonce for inline style tags |
Embedded Mode
Embedded mode renders the panel inline as a regular component. Use ReactQueryDevtoolsPanel for custom layouts or dashboards.
import { useState } from 'react';
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
function DebugPanel() {
const [isOpen, setIsOpen] = useState(true);
if (!isOpen) return null;
return (
<div style={{ height: 300 }}>
<ReactQueryDevtoolsPanel
style={{ height: '100%' }}
onClose={() => setIsOpen(false)}
/>
</div>
);
}Embedded Mode Props
| Prop | Type | Description |
|---|---|---|
style | React.CSSProperties | Inline styles for the panel container |
className | string | CSS class for the panel container |
client | QueryClient | Custom QueryClient instance |
errorTypes | { name: string; initializer: (query: Query) => TError }[] | Predefined errors to trigger from UI |
styleNonce | string | CSP nonce for inline style tags |
onClose | () => void | Callback when panel close button is clicked |
Production Builds
By default, ReactQueryDevtools is excluded from production bundles via process.env.NODE_ENV checks. To opt in to production devtools, use the production export:
import { ReactQueryDevtools } from '@tanstack/react-query-devtools/production';ReactQueryDevtoolsPanel also has a /production export for embedded mode in production environments.
Lazy Loading
Reduce development bundle impact by lazy-loading devtools:
import { lazy, Suspense } from 'react';
const ReactQueryDevtools = lazy(() =>
import('@tanstack/react-query-devtools').then((mod) => ({
default: mod.ReactQueryDevtools,
})),
);
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
<Suspense fallback={null}>
<ReactQueryDevtools />
</Suspense>
</QueryClientProvider>
);
}Devtools Features
The query devtools panel provides:
- Query list: All cached queries with status indicators (fresh, stale, inactive, fetching)
- Query detail: Selected query data, metadata, and timing information
- Cache actions: Manually refetch, invalidate, reset, or remove individual queries
- Error simulation: Trigger predefined errors on queries via the
errorTypesprop - Filter and sort: Search queries by key and sort by status, last updated, or key hash
Integration with Unified Devtools
Query devtools can also run as a plugin in the unified TanStack Devtools panel. See the form devtools and unified patterns reference for the plugin approach.
import { TanStackDevtools } from '@tanstack/react-devtools';
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
<TanStackDevtools
plugins={[
{
id: 'tanstack-query',
name: 'TanStack Query',
render: <ReactQueryDevtoolsPanel />,
},
]}
/>;Router Devtools
Installation
pnpm add @tanstack/react-router-devtoolsThe package is separate from @tanstack/react-router. Devtools are automatically excluded from production bundles by default.
Floating Mode
Place TanStackRouterDevtools inside a route component (typically the root route) for automatic router detection via context. Panel toggle state persists in localStorage.
Inside Root Route (Recommended)
import { createRootRoute, Outlet } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
export const Route = createRootRoute({
component: () => (
<>
<Outlet />
<TanStackRouterDevtools />
</>
),
});Outside RouterProvider
When rendering outside the provider, pass the router instance explicitly:
import { RouterProvider, createRouter } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
const router = createRouter({ routeTree });
function App() {
return (
<>
<RouterProvider router={router} />
<TanStackRouterDevtools router={router} />
</>
);
}Floating Mode Props
| Prop | Type | Default | Description |
|---|---|---|---|
router | Router | nearest context | Router instance (required outside provider) |
initialIsOpen | boolean | false | Whether devtools panel starts open |
panelProps | object | — | Props passed to the panel (className, style) |
toggleButtonProps | object | — | Props passed to the toggle button |
position | `'top-left' \ | 'top-right' \ | 'bottom-left' \ |
Embedded Mode
Use TanStackRouterDevtoolsPanel for inline rendering in custom layouts:
import { useState } from 'react';
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
function RouterDebugPanel({ router }: { router: Router }) {
const [isOpen, setIsOpen] = useState(true);
return (
<div style={{ height: 400 }}>
<TanStackRouterDevtoolsPanel
router={router}
isOpen={isOpen}
setIsOpen={setIsOpen}
style={{ height: '100%' }}
/>
</div>
);
}Embedded Mode Props
| Prop | Type | Description |
|---|---|---|
router | Router | Router instance to connect to |
style | React.CSSProperties | Inline styles for the panel |
className | string | CSS class for the panel |
isOpen | boolean | Controls panel open/close state |
setIsOpen | (open: boolean) => void | Toggles panel open/close state |
handleDragStart | (e: MouseEvent) => void | Drag handler for resizable panels |
Production Builds
By default, TanStackRouterDevtools is excluded from production bundles. To enable devtools in production, import the production variant:
import { TanStackRouterDevtoolsInProd } from '@tanstack/react-router-devtools';TanStackRouterDevtoolsInProd accepts the same props as TanStackRouterDevtools.
Lazy Loading
Code-split devtools to keep them out of the initial bundle:
import { lazy, Suspense } from 'react';
const TanStackRouterDevtools = lazy(() =>
import('@tanstack/react-router-devtools').then((mod) => ({
default: mod.TanStackRouterDevtools,
})),
);
export const Route = createRootRoute({
component: () => (
<>
<Outlet />
<Suspense fallback={null}>
<TanStackRouterDevtools />
</Suspense>
</>
),
});Devtools Features
The router devtools panel provides:
- Route tree visualization: Full route hierarchy with active route highlighting
- Match inspection: Current route matches with params, search params, and loader data
- Route timing: Load and pending timing for each matched route
- Search param viewer: Parsed and serialized search parameters
- Navigation history: Recent navigations with details
Integration with Unified Devtools
Router devtools can run as a plugin in the unified TanStack Devtools panel:
import { TanStackDevtools } from '@tanstack/react-devtools';
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
<TanStackDevtools
plugins={[
{
id: 'tanstack-router',
name: 'TanStack Router',
render: <TanStackRouterDevtoolsPanel router={router} />,
},
]}
/>;When using the unified panel, pass the router prop explicitly to the panel component since it renders outside the RouterProvider context.