Developer tools to interact with and visualize the TanStack/react-query cache
npx @tessl/cli install tessl/npm-tanstack--react-query-devtools@5.86.0TanStack React Query Devtools provides React-specific developer tools for TanStack Query (formerly React Query), enabling developers to inspect, debug, and visualize query cache state, mutations, and data fetching operations in React applications. It offers both floating devtools components and embedded panels that integrate directly into applications during development.
npm install @tanstack/react-query-devtools or pnpm add @tanstack/react-query-devtoolsimport { ReactQueryDevtools, ReactQueryDevtoolsPanel, type DevtoolsPanelOptions } from "@tanstack/react-query-devtools";For production builds (always renders devtools):
import { ReactQueryDevtools, ReactQueryDevtoolsPanel } from "@tanstack/react-query-devtools/production";
// Note: No types are exported from the production entry point
// Import types from main entry if needed: import type { DevtoolsPanelOptions } from "@tanstack/react-query-devtools";import React from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<div className="app">
{/* Your app components */}
</div>
{/* Floating devtools - only shows in development */}
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}The devtools package provides two distinct components:
Both components internally wrap the core TanstackQueryDevtools and TanstackQueryDevtoolsPanel classes from @tanstack/query-devtools, providing React-specific lifecycle management and context integration.
A toggleable floating devtools interface with customizable positioning and appearance options.
/**
* Main floating devtools component with toggle button
* Returns null in production unless imported from /production entry
*/
function ReactQueryDevtools(props: DevtoolsOptions): React.ReactElement | null;
interface DevtoolsOptions {
/** Set to true to default devtools to open state */
initialIsOpen?: boolean;
/** Position of toggle button - defaults to 'bottom-right' */
buttonPosition?: DevtoolsButtonPosition;
/** Position of devtools panel - defaults to 'bottom' */
position?: DevtoolsPosition;
/** Custom QueryClient instance */
client?: QueryClient;
/** Custom error types for devtools display */
errorTypes?: Array<DevtoolsErrorType>;
/** CSP nonce for inline styles */
styleNonce?: string;
/** Attach styles to specific DOM element */
shadowDOMTarget?: ShadowRoot;
/** Hide disabled queries from panel */
hideDisabledQueries?: boolean;
}Usage Examples:
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
// Basic usage with default options
<ReactQueryDevtools />
// Customized positioning and initial state
<ReactQueryDevtools
initialIsOpen={true}
buttonPosition="top-left"
position="right"
/>
// With custom error types and CSP nonce
<ReactQueryDevtools
errorTypes={[
{
name: "CustomError",
initializer: (query) => new Error(`Custom error for ${query.queryKey}`)
}
]}
styleNonce="my-csp-nonce"
hideDisabledQueries={true}
/>An always-visible embedded devtools panel that integrates directly into your application layout.
/**
* Embedded devtools panel component (always visible)
* Returns null in production unless imported from /production entry
*/
function ReactQueryDevtoolsPanel(props: DevtoolsPanelOptions): React.ReactElement | null;
interface DevtoolsPanelOptions {
/** Custom QueryClient instance */
client?: QueryClient;
/** Custom error types for devtools display */
errorTypes?: Array<DevtoolsErrorType>;
/** CSP nonce for inline styles */
styleNonce?: string;
/** Attach styles to specific DOM element */
shadowDOMTarget?: ShadowRoot;
/** Custom panel styles - defaults to { height: '500px' } */
style?: React.CSSProperties;
/** Callback when panel is closed */
onClose?: () => unknown;
/** Hide disabled queries from panel */
hideDisabledQueries?: boolean;
}Usage Examples:
import { ReactQueryDevtoolsPanel } from "@tanstack/react-query-devtools";
// Basic embedded panel
<ReactQueryDevtoolsPanel />
// Full-height panel with close handler
<ReactQueryDevtoolsPanel
style={{ height: "100vh" }}
onClose={() => console.log("Panel closed")}
/>
// Panel with custom dimensions and error handling
<ReactQueryDevtoolsPanel
style={{
height: "600px",
width: "100%",
border: "1px solid #ccc"
}}
errorTypes={customErrorTypes}
hideDisabledQueries={true}
/>/** Position options for the devtools toggle button */
type DevtoolsButtonPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'relative';
/** Position options for the devtools panel */
type DevtoolsPosition = 'top' | 'bottom' | 'left' | 'right';/** Custom error type configuration for devtools display */
interface DevtoolsErrorType {
/** Name of the error type */
name: string;
/** Function to initialize the error from a query */
initializer: (query: Query) => Error;
}/** Re-exported configuration options for ReactQueryDevtoolsPanel */
type DevtoolsPanelOptions = {
client?: QueryClient;
errorTypes?: Array<DevtoolsErrorType>;
styleNonce?: string;
shadowDOMTarget?: ShadowRoot;
style?: React.CSSProperties;
onClose?: () => unknown;
hideDisabledQueries?: boolean;
};The main entry point includes automatic production environment detection:
NODE_ENV === 'development'): Components render normally with full functionalityNODE_ENV !== 'development'): Components return null to prevent devtools from appearing in production buildsFor debugging production builds or when you need devtools to always render:
import { ReactQueryDevtools } from "@tanstack/react-query-devtools/production";
// This will always render devtools regardless of NODE_ENVRequired peer dependencies that must be installed separately:
@tanstack/react-query (workspace:^) - Core React Query functionalityreact (^18 || ^19) - React frameworkBoth components require a QueryClient to be available via React context:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app and devtools components */}
</QueryClientProvider>
);
}You can optionally pass a custom QueryClient instance to either component:
const customClient = new QueryClient({
defaultOptions: {
queries: { staleTime: 60000 }
}
});
<ReactQueryDevtools client={customClient} />For applications using Content Security Policy with nonce-based inline styles:
<ReactQueryDevtools
styleNonce="your-csp-nonce"
/>
<ReactQueryDevtoolsPanel
styleNonce="your-csp-nonce"
/>For applications using Shadow DOM, you can attach devtools styles to a specific shadow root:
const shadowRoot = document.querySelector('#shadow-host').shadowRoot;
<ReactQueryDevtools
shadowDOMTarget={shadowRoot}
/>If devtools fail to render, ensure QueryClientProvider wraps your components:
// ❌ Missing QueryClientProvider
function App() {
return <ReactQueryDevtools />;
}
// ✅ Proper setup
function App() {
return (
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools />
</QueryClientProvider>
);
}If devtools appear in production builds unexpectedly, check your import path:
// ❌ Will not render in production
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
// ✅ Will always render (use only for debugging production)
import { ReactQueryDevtools } from "@tanstack/react-query-devtools/production";