Overview
TanStack Devtools provides a unified debugging interface that consolidates devtools for TanStack Query, Router, and other libraries into a single panel. It features a framework-agnostic plugin architecture, real-time state inspection, and support for custom plugins. Built with Solid.js for lightweight performance.
React: @tanstack/react-devtools
Core: @tanstack/devtools
Status: Alpha
Installation
npm install @tanstack/react-devtools
Basic Setup
import { TanStackDevtools } from '@tanstack/react-devtools' import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
function App() { return ( <QueryClientProvider client={queryClient}> <TanStackDevtools /> {/* Your app content */} <MyApp /> </QueryClientProvider> ) }
Built-in Plugins
Query Devtools
import { TanStackDevtools } from '@tanstack/react-devtools' import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'
function App() { return ( <QueryClientProvider client={queryClient}> <TanStackDevtools plugins={[ { id: 'react-query', name: 'React Query', render: () => <ReactQueryDevtoolsPanel />, }, ]} /> <MyApp /> </QueryClientProvider> ) }
Router Devtools
import { TanStackDevtools } from '@tanstack/react-devtools' import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
function App() { return ( <TanStackDevtools plugins={[ { id: 'router', name: 'Router', render: () => <TanStackRouterDevtoolsPanel router={router} />, }, ]} /> ) }
Combined Setup
import { TanStackDevtools } from '@tanstack/react-devtools' import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools' import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
function App() { return ( <QueryClientProvider client={queryClient}> <TanStackDevtools plugins={[ { id: 'react-query', name: 'React Query', render: () => <ReactQueryDevtoolsPanel />, }, { id: 'router', name: 'Router', render: () => <TanStackRouterDevtoolsPanel router={router} />, }, ]} /> <MyApp /> </QueryClientProvider> ) }
AI Devtools
For debugging TanStack AI workflows:
import { TanStackDevtools } from '@tanstack/react-devtools' import { AIDevtoolsPanel } from '@tanstack/ai-react/devtools'
function App() { return ( <TanStackDevtools plugins={[ { id: 'ai', name: 'AI', render: () => <AIDevtoolsPanel />, }, ]} /> ) }
AI Devtools features:
-
Message Inspector - View full conversation history with metadata
-
Token Usage - Track input/output tokens and costs per request
-
Streaming Visualization - Real-time view of streaming chunks
-
Tool Call Debugging - Inspect tool calls, parameters, and results
-
Thinking/Reasoning Viewer - Debug reasoning tokens from thinking models
-
Adapter Switching - Test different providers in development
Plugin System
Plugin Interface
interface DevtoolsPlugin { id: string // Unique identifier name: string // Display name in the devtools panel render: () => JSX.Element // React component to render }
Custom Plugins
import { TanStackDevtools } from '@tanstack/react-devtools'
// Custom state inspector plugin const stateInspectorPlugin = { id: 'state-inspector', name: 'State', render: () => ( <div style={{ padding: '16px' }}> <h3>Application State</h3> <pre>{JSON.stringify(appState, null, 2)}</pre> </div> ), }
// Custom network logger plugin const networkLoggerPlugin = { id: 'network-logger', name: 'Network', render: () => <NetworkLoggerPanel />, }
function App() { return ( <TanStackDevtools plugins={[ stateInspectorPlugin, networkLoggerPlugin, ]} /> ) }
Dynamic Plugin Registration
function App() { const [plugins, setPlugins] = useState<DevtoolsPlugin[]>([])
useEffect(() => { // Register plugins conditionally const activePlugins: DevtoolsPlugin[] = []
if (process.env.NODE_ENV === 'development') {
activePlugins.push({
id: 'debug',
name: 'Debug',
render: () => <DebugPanel />,
})
}
setPlugins(activePlugins)
}, [])
return <TanStackDevtools plugins={plugins} /> }
Vite Plugin Integration
// vite.config.ts import { defineConfig } from 'vite' import { tanstackDevtools } from '@tanstack/devtools/vite'
export default defineConfig({ plugins: [ tanstackDevtools(), ], })
Production Considerations
// Only include devtools in development function App() { return ( <> {process.env.NODE_ENV === 'development' && ( <TanStackDevtools plugins={plugins} /> )} <MyApp /> </> ) }
// Or use lazy loading const TanStackDevtools = lazy(() => import('@tanstack/react-devtools').then((m) => ({ default: m.TanStackDevtools })) )
Framework Support
Framework Package Status
React @tanstack/react-devtools
Alpha
Solid @tanstack/solid-devtools
Planned
Vue @tanstack/vue-devtools
Planned
Angular @tanstack/angular-devtools
Planned
Features
-
Unified Panel - Single interface for all TanStack debugging
-
Real-time Updates - Live monitoring of state changes
-
Plugin Architecture - Extensible with custom and third-party plugins
-
Built-in Plugins - Query, Router, and AI devtools panels
-
Lightweight - Built with Solid.js for minimal overhead
-
Type-safe - Full TypeScript support for plugin definitions
-
Framework-agnostic Core - Plugin logic works across frameworks
Best Practices
-
Conditionally include in production - use environment checks or code splitting
-
Use specific plugins rather than loading all available ones
-
Give plugins unique IDs to prevent conflicts
-
Keep plugin render functions lightweight - avoid expensive computations
-
Use the Vite plugin for automatic setup in Vite-based projects
-
Combine Query + Router + AI plugins for full-stack TanStack debugging
-
Create domain-specific plugins for app-level state inspection
-
Use AI devtools when debugging streaming, tool calls, or token usage
Common Pitfalls
-
Including devtools in production builds without tree-shaking
-
Using duplicate plugin IDs (causes rendering conflicts)
-
Heavy render functions in plugins (slows down the devtools panel)
-
Forgetting to wrap with QueryClientProvider when using Query plugin
-
Not passing the router instance to Router devtools panel