Overview

React Query, a core component of TanStack Query, is a library designed to simplify server state management within client-side applications. It provides a set of hooks for fetching, caching, synchronizing, and updating asynchronous data, primarily in React applications, though the broader TanStack Query project supports frameworks like Vue, Svelte, and Solid. The library addresses challenges associated with server state, which differs from client state (like UI theme or form input values) in that it is persistent, asynchronous, and often mutable by other users or processes. Managing server state in client applications involves complexities such as data staleness, background refetching, caching, pagination, and error handling, which React Query aims to abstract and automate.

React Query is particularly well-suited for applications that frequently interact with APIs to fetch or mutate data. It helps developers avoid manual data fetching logic, race conditions, and inconsistent UI states by offering a declarative approach to data management. The library automatically handles caching fetched data, providing immediate access to previously loaded information and reducing the need for repeated network requests. This leads to improved application performance and a smoother user experience, as content can be displayed quickly, even on subsequent visits or component remounts.

The library's design focuses on developer experience, providing tools like the TanStack Query Devtools for visualizing and debugging query states, cache contents, and mutations. It supports advanced patterns such as optimistic updates, where the UI is updated immediately after a data mutation request, assuming the request will succeed, and then rolled back if an error occurs. This creates a highly responsive user interface. Additionally, React Query offers features like automatic retries on failed queries, data prefetching, and configurable stale-while-revalidate strategies, aligning with modern web development practices for robust and efficient data handling.

While primarily associated with React, the underlying principles and API surface have been adapted for other frameworks, demonstrating its versatility across the JavaScript ecosystem. Developers often choose React Query for its opinionated yet flexible approach to server state, reducing boilerplate code and centralizing data management concerns away from components, thereby improving code maintainability and testability. For instance, managing data fetching with a library like SWR also focuses on similar patterns, as described in their documentation on data fetching strategies, highlighting a common need across modern web development for efficient asynchronous data handling.

Key features

  • Declarative Data Fetching: Utilize hooks like useQuery and useInfiniteQuery to declare data requirements, letting React Query manage the fetching, caching, and synchronization process automatically.
  • Automatic Caching and Refetching: Data is cached by default, and stale data is automatically refetched in the background to keep the UI up-to-date without blocking user interaction.
  • Optimistic UI Updates: Implement immediate UI updates for mutations, assuming success, and roll back changes if the server response indicates an error, enhancing perceived performance and responsiveness.
  • Background Data Synchronization: Automatically synchronizes server state with client-side state, ensuring data consistency across the application.
  • Query Invalidation: Programmatically invalidate cached data to trigger refetching for specific queries, ensuring data freshness after mutations or external events.
  • Configurable Retries and Error Handling: Automatically retries failed queries with exponential backoff and provides flexible error handling mechanisms.
  • Pagination and Infinite Loading: Built-in support for managing paginated and infinitely scrolling lists, simplifying the implementation of complex data displays.
  • SSR and SSG Compatibility: Provides utilities and patterns for pre-fetching data on the server for Server-Side Rendering (SSR) and Static Site Generation (SSG) environments, enabling faster initial page loads.
  • Devtools Integration: Offers a dedicated Devtools panel for inspecting query states, cache contents, and debugging data flow within the application.
  • Type Safety with TypeScript: Designed with TypeScript in mind, providing strong type inference and safety for queries, mutations, and cached data.

Pricing

React Query, as part of TanStack Query, is distributed under an MIT License.

TierDescriptionAvailability
Open-SourceFull access to all features, source code, and community support.Free

As of May 8, 2026, React Query remains a fully open-source project with no paid tiers or commercial licenses offered directly by TanStack for its core functionalities. The project relies on community contributions and sponsorship.

Common integrations

  • React: Core integration via react-query package for managing server state in React applications. Developers can find comprehensive guides on the React Query documentation.
  • Next.js: Integrated for server-side rendering (SSR) and static site generation (SSG) to pre-fetch data on the server, improving initial load performance. The Next.js documentation provides context on data fetching in server components.
  • Vue.js: Supported through vue-query, extending the same data fetching and caching capabilities to Vue applications. Detailed instructions are available in the Vue Query documentation.
  • Solid.js: Support via solid-query, enabling reactive data fetching and state management within Solid.js applications. Refer to the Solid Query documentation for usage.
  • Svelte: Integrated through svelte-query, bringing React Query's features to Svelte applications. The Svelte Query documentation outlines its implementation.
  • Axios / Fetch API: Commonly used with standard HTTP clients like Fetch API or Axios for making network requests. React Query is agnostic to the data fetching library, allowing developers to use their preferred method within query functions.

Alternatives

  • SWR: A React Hooks library for data fetching, also based on the stale-while-revalidate strategy, offering a lightweight alternative for similar use cases.
  • Apollo Client: A comprehensive state management library for GraphQL, providing caching, normalized store, and advanced features for GraphQL-centric applications.
  • RTK Query: A data fetching and caching solution built on top of Redux Toolkit, offering a centralized approach to API interactions and state management within Redux ecosystems.
  • Redux (manual data fetching): While Redux itself is a general-purpose state container, it can be used for server state management with manual implementation of fetching, caching, and invalidation logic, often requiring more boilerplate.
  • Remix Data Loading: Remix's built-in data loading mechanisms, such as loader functions, provide integrated server-side data fetching and revalidation capabilities for Remix applications.

Getting started

To begin using React Query in a React application, you first need to install the package and set up a QueryClientProvider to provide the QueryClient instance to your application. This client manages the cache and all query interactions. Below is a basic example demonstrating how to fetch and display data.

First, install React Query:

npm install @tanstack/react-query
# or
yarn add @tanstack/react-query
# or
pnpm add @tanstack/react-query

Then, set up the QueryClientProvider in your root component (e.g., index.js or App.js) and define a simple data fetching hook:

// App.js
import React from 'react';
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';

const queryClient = new QueryClient();

function Todos() {
  const { isLoading, error, data } = useQuery({
    queryKey: ['todos'],
    queryFn: () =>
      fetch('https://jsonplaceholder.typicode.com/todos')
        .then(res => res.json())
  });

  if (isLoading) return "<p>Loading...</p>";
  if (error) return "<p>An error has occurred: " + error.message + "</p>";

  return (
    <div>
      <h1>Todos</h1>
      <ul>
        {data.map(todo => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  );
}

In this example, useQuery is used to fetch a list of to-do items from a public API. The queryKey ['todos'] uniquely identifies this query in the cache. The queryFn is an asynchronous function that performs the actual data fetching. React Query handles the loading, error states, and caching of the fetched data, making these states available directly from the hook. When the Todos component mounts, data is fetched. If the component unmounts and remounts, React Query will serve the cached data immediately while potentially refetching in the background if the data is considered stale based on configured options.