Skip to main content

Installation

Learn how to install and set up TanStack Query in your React application.

Requirements

TanStack Query is compatible with React v18 and v19.
  • React 18.0.0 or later
  • React 19.0.0 or later
React Query version 5.90.21 and above supports both React 18 and React 19. Make sure you’re using a compatible version.

Package Installation

1

Install the package

Install TanStack Query using your preferred package manager:
npm install @tanstack/react-query
2

Install DevTools (Optional)

For development, install the DevTools package:
npm install @tanstack/react-query-devtools
The DevTools package is tree-shakeable and only includes development code when NODE_ENV !== 'production', so it’s safe to include in production builds.

Setup

1

Create a QueryClient

Create a QueryClient instance to manage queries and mutations:
import { QueryClient } from '@tanstack/react-query'

const queryClient = new QueryClient()
You can configure default options for all queries and mutations:
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000, // 1 minute
      gcTime: 10 * 60 * 1000, // 10 minutes
      retry: 1,
      refetchOnWindowFocus: false,
    },
    mutations: {
      retry: 0,
    },
  },
})
2

Wrap your app with QueryClientProvider

Provide the QueryClient to your React app using the QueryClientProvider:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

const queryClient = new QueryClient()

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* Your app components */}
    </QueryClientProvider>
  )
}

export default App
3

Add DevTools (Development)

Import and add the DevTools component for development:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

const queryClient = new QueryClient()

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* Your app components */}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  )
}

export default App
The DevTools component only renders in development mode (NODE_ENV === 'development'), so you don’t need to conditionally import it.

Complete Example

Here’s a complete setup example:
src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import App from './App'

// Create a client
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000,
      retry: 1,
    },
  },
})

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  </React.StrictMode>,
)

Configuration Options

Customize the QueryClient with these common options:

Query Options

OptionTypeDefaultDescription
staleTimenumber | Infinity0Time in ms until data becomes stale
gcTimenumber | Infinity5 * 60 * 1000Time in ms unused data stays in cache
retryboolean | number | function3Number of retry attempts for failed queries
retryDelaynumber | functionexponential backoffDelay between retries
refetchOnWindowFocusboolean | "always"trueRefetch on window focus
refetchOnMountboolean | "always"trueRefetch on component mount
refetchOnReconnectboolean | "always"trueRefetch when reconnecting
refetchIntervalnumber | falsefalseInterval for automatic refetching

Mutation Options

OptionTypeDefaultDescription
retryboolean | number | function0Number of retry attempts for failed mutations
retryDelaynumber | functionexponential backoffDelay between retries
Be careful with aggressive retry settings in production, as they can impact server load and user experience.

Environment-Specific Configuration

Configure different settings for development and production:
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: process.env.NODE_ENV === 'production' ? 60 * 1000 : 0,
      gcTime: process.env.NODE_ENV === 'production' ? 10 * 60 * 1000 : 5 * 60 * 1000,
      retry: process.env.NODE_ENV === 'production' ? 3 : 1,
      refetchOnWindowFocus: process.env.NODE_ENV === 'production',
    },
  },
})

Next.js Setup

For Next.js applications, create a separate client component:
app/providers.tsx
'use client'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { useState } from 'react'

export function Providers({ children }: { children: React.ReactNode }) {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            staleTime: 60 * 1000,
          },
        },
      }),
  )

  return (
    <QueryClientProvider client={queryClient}>
      {children}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  )
}
Then use it in your root layout:
app/layout.tsx
import { Providers } from './providers'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}
Always create the QueryClient inside a component using useState to ensure each request gets a new client instance in Server Components.

Persister Setup (Optional)

To persist query cache across sessions:
npm install @tanstack/react-query-persist-client
import { QueryClient } from '@tanstack/react-query'
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      gcTime: 1000 * 60 * 60 * 24, // 24 hours
    },
  },
})

const persister = createSyncStoragePersister({
  storage: window.localStorage,
})

function App() {
  return (
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{ persister }}
    >
      {/* Your app */}
    </PersistQueryClientProvider>
  )
}

Verification

Verify your installation by creating a simple query:
src/App.tsx
import { useQuery } from '@tanstack/react-query'

function App() {
  const { data, isLoading } = useQuery({
    queryKey: ['hello'],
    queryFn: async () => {
      const response = await fetch('https://api.example.com/hello')
      return response.json()
    },
  })

  if (isLoading) return <div>Loading...</div>

  return <div>Data: {JSON.stringify(data)}</div>
}

export default App
If you see the DevTools floating button in the bottom-right corner of your app, React Query is successfully installed!

Next Steps

Quick Start

Build your first React Query application

TypeScript

Configure TypeScript for type-safe queries

Build docs developers (and LLMs) love