Overview
@tanstack/react-query, commonly known as React Query, is a library designed to simplify server state management in React applications. Unlike client state libraries that focus on UI interactions, React Query specializes in asynchronous data operations, including fetching, caching, synchronizing, and updating server data. It provides a set of hooks that abstract away the complexities of managing network requests, stale data, and data consistency across components.
The library automates many common tasks associated with server state, such as caching fetched data to prevent redundant requests, background refetching to ensure data freshness, and invalidation mechanisms to update stale data. This automation contributes to a more responsive user experience and reduces the amount of boilerplate code developers need to write for data handling. For example, when a user navigates away from a page and returns, React Query can serve cached data instantly while silently refetching the latest version in the background, providing an immediate UI response.
React Query is particularly well-suited for applications that rely heavily on data fetched from APIs, where managing loading states, error handling, and data synchronization can become complex. It supports optimistic UI updates, allowing developers to immediately reflect the expected outcome of a mutation in the UI before the server confirms the change. If the server request fails, the UI can automatically revert to its previous state. This approach can enhance perceived performance and user satisfaction.
While originally developed for React, the underlying TanStack Query library has expanded to support other frameworks like Vue, Solid, Svelte, and Qwik, offering a consistent API for server state management across different ecosystems. Its focus on declarative data fetching and robust caching strategies positions it as a tool for modern web development, aiming to streamline the interaction between client-side applications and backend data sources.
Managing server state effectively is a distinct challenge from managing client-side UI state. While tools like Redux (with RTK Query) or Apollo Client (for GraphQL) also address server state, React Query focuses specifically on RESTful and similar data fetching patterns, offering a lightweight alternative for React applications that may not require a full-fledged GraphQL client or a Redux-centric architecture. Its design principles align with the React component lifecycle, making it a natural fit for developers accustomed to React's declarative programming model.
Key features
- Declarative Data Fetching: Provides hooks (e.g.,
useQuery,useMutation) to declare data requirements, simplifying fetching, caching, and error handling. - Automatic Caching and Deduplication: Caches query results and deduplicates identical requests to prevent redundant network calls, improving performance and reducing server load.
- Background Refetching: Automatically refetches stale data in the background to ensure data freshness without blocking the UI.
- Stale-While-Revalidate Strategy: Serves cached data immediately while asynchronously refetching the latest version, providing a fast initial load.
- Optimistic Updates: Allows developers to update the UI instantly after a mutation, assuming success, and provides rollback mechanisms if the server operation fails.
- Pagination and Infinite Loading: Built-in support for implementing pagination and infinite scroll patterns for large datasets.
- Query Invalidation: Provides mechanisms to mark data as stale and trigger refetches across the application, ensuring data consistency after mutations.
- Automatic Retries: Configurable automatic retries for failed queries, enhancing resilience against transient network issues.
- Devtools: Includes a dedicated browser devtool for inspecting query states, cache contents, and debugging data flows.
Pricing
As of June 2026, @tanstack/react-query is distributed under an MIT License, making it free and open-source for all use cases. There are no paid tiers or commercial licenses offered for the core library functionality.
| Feature | Availability | Notes |
|---|---|---|
| Core Library | Free | Includes all data fetching, caching, and synchronization features. |
| Documentation & Community Support | Free | Access to comprehensive documentation and community forums. |
| Commercial Support | Not offered directly | Support is community-driven. |
Common integrations
- React: Primary integration via hooks like
useQueryanduseMutationfor server state management in React applications. For detailed usage, refer to the React Query API reference. - Axios: Commonly used with HTTP client libraries such as Axios for making API requests within query functions.
- GraphQL Clients: Can be integrated with GraphQL clients like Apollo Client or Relay for fetching data, although React Query typically focuses on RESTful APIs. For specific GraphQL implementations, developers might prefer dedicated GraphQL state management tools.
- Other TanStack Libraries: Seamlessly integrates with other libraries from the TanStack suite, such as TanStack Table for displaying fetched data or TanStack Router for managing routing alongside data dependencies.
- Next.js / Remix: Can be used within server-rendered or static-generated React frameworks like Next.js and Remix, though specific server-side rendering patterns require careful implementation.
Alternatives
- SWR: A React Hooks library for data fetching, also based on a stale-while-revalidate strategy, offering a lightweight alternative.
- Apollo Client: A comprehensive state management library for GraphQL, providing caching, local state management, and UI integration.
- RTK Query: Part of Redux Toolkit, providing a powerful data fetching and caching solution built on top of Redux.
Getting started
To begin using @tanstack/react-query in a React application, install the package and set up a QueryClientProvider. This provider makes the query client available to all components within its scope. The following example demonstrates basic data fetching using the useQuery hook:
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
import React from 'react';
const queryClient = new QueryClient();
interface Todo {
id: number;
title: string;
completed: boolean;
}
function Todos() {
const { isLoading, error, data } = useQuery<Todo[], Error>({
queryKey: ['todos'],
queryFn: () =>
fetch('https://jsonplaceholder.typicode.com/todos')
.then(res => res.json()),
});
if (isLoading) return <p>Loading todos...</p>;
if (error) return <p>An error occurred: {error.message}</p>;
return (
<div>
<h1>Todos</h1>
<ul>
{data?.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
</div>
);
}
function App() {
return (
<QueryClientProvider client={queryClient}>
<Todos />
</QueryClientProvider>
);
}
export default App;
In this example, useQuery is called with a unique queryKey (['todos']) and a queryFn that performs the actual data fetching. React Query handles the loading, error, and data states, making them accessible directly from the hook's return value. The QueryClientProvider ensures that the query client, which manages caching and requests, is available to the Todos component and any other component within its scope.