Overview

React Query, now known as TanStack Query, is a data-fetching library designed to simplify the management of asynchronous server state in web applications. While initially developed for React, its core logic has been extracted into a framework-agnostic library, TanStack Query, with adapters available for various frontend frameworks including Solid, Vue, and Svelte [TanStack Query Docs]. The library addresses common challenges associated with fetching, caching, synchronizing, and updating server data, which often differs from client-side state due to its asynchronous nature and persistence requirements.

Traditional client-side state management libraries, such as Redux or Zustand, are primarily designed for local, synchronous application state. Server state, however, introduces complexities like caching, invalidation, background refetching, and ensuring data freshness. React Query provides a set of hooks that abstract away much of this complexity, allowing developers to focus on application logic rather than boilerplate data management. It automatically handles data caching, reducing redundant network requests and improving application performance. For instance, when a user navigates away from a page and then returns, React Query can serve stale data instantly while simultaneously refetching fresh data in the background, providing a smoother user experience [TanStack Query React Query Basics].

The library is particularly well-suited for applications that frequently interact with APIs, such as dashboards, e-commerce sites, or social media platforms, where data freshness is important but immediate consistency isn't always required. It excels in scenarios involving optimistic UI updates, where the UI is updated immediately after a user action, assuming the server operation will succeed, and then reverted if an error occurs. This pattern enhances perceived performance and responsiveness [TanStack Query Optimistic Updates]. React Query also offers robust error handling, retry mechanisms, and the ability to prefetch data, contributing to a more resilient and performant user interface.

Key features

  • Automatic Caching: Automatically caches fetched data to prevent redundant network requests and improve load times. Data is stored in a normalized cache, which can be configured for various invalidation strategies [TanStack Query Caching Guide].
  • Background Refetching: Automatically refetches data in the background when certain conditions are met, such as window focus, network reconnection, or component remount, ensuring data remains fresh without explicit user interaction [TanStack Query Background Fetching].
  • Optimistic UI Updates: Supports updating the UI instantly after a data mutation, assuming the server operation will succeed, and provides mechanisms to roll back the UI state if the mutation fails. This improves perceived performance [TanStack Query Optimistic Updates].
  • Query Invalidation and Refetching: Provides tools to manually or programmatically invalidate cached queries, triggering a refetch of the associated data to ensure UI reflects the latest server state. This is crucial for mutations that affect multiple parts of the application [TanStack Query Invalidation Guide].
  • Automatic Retries: Configurable automatic retry logic for failed queries, with exponential backoff, to handle transient network issues or server errors without requiring manual intervention from the developer [TanStack Query Automatic Retries].
  • Pagination and Infinite Loading: Built-in support for implementing pagination and infinite scrolling patterns, simplifying the management of large datasets and enhancing user experience [TanStack Query Infinite Queries].
  • Prefetching Data: Allows developers to prefetch data before it's needed, for example, when a user hovers over a link, reducing loading times when the user navigates to the associated page [TanStack Query Prefetching].
  • Devtools: Includes a dedicated browser devtools extension that provides insights into the query cache, status, and network requests, aiding in debugging and performance optimization [TanStack Query Devtools].

Pricing

As of May 2026, TanStack Query, including its React Query adapter, is distributed under the MIT License and is fully open-source and free to use.

Feature Availability (as of May 2026)
Core Library Free and open-source [TanStack Query Homepage]
React Adapter Free and open-source [TanStack Query Homepage]
Solid Adapter Free and open-source [TanStack Query Homepage]
Vue Adapter Free and open-source [TanStack Query Homepage]
Svelte Adapter Free and open-source [TanStack Query Homepage]
Devtools Free and open-source [TanStack Query Devtools]

Common integrations

  • React: Primary integration via @tanstack/react-query package, providing hooks like useQuery and useMutation [TanStack React Query Overview].
  • Next.js: Often used with Next.js for server-side rendering (SSR) and static site generation (SSG) scenarios, requiring specific configurations for data hydration [TanStack Query SSR Guide].
  • Astro: Can be integrated into Astro projects using the React adapter for client-side data fetching within React components [Astro React Integration Guide].
  • Vue: Integrated via @tanstack/vue-query, offering a similar API with Vue-specific composables [TanStack Vue Query Overview].
  • Svelte: Integration available through @tanstack/svelte-query, providing reactive stores and functions for Svelte applications [TanStack Svelte Query Overview].
  • Remix: Compatible with Remix for data fetching, though Remix's built-in data loading mechanisms (loaders and actions) often serve similar purposes, requiring careful consideration of when to use each [Remix Data Flow Guide].
  • Axios/Fetch API: Commonly used with standard HTTP clients like Axios or the native Fetch API for making network requests within query functions [MDN Fetch API].

Alternatives

  • SWR: A React Hooks library for data fetching that emphasizes stale-while-revalidate caching strategy, developed by Vercel.
  • Apollo Client: A comprehensive state management library for GraphQL, offering sophisticated caching, normalized store, and optimistic UI capabilities.
  • Redux Toolkit Query (RTK Query): An opinionated data fetching and caching solution built on top of Redux Toolkit, providing similar features to React Query within the Redux ecosystem.
  • React Context API + useReducer: Native React features that can be combined to manage global client-side state, though they require more manual implementation for server state concerns like caching and refetching.

Getting started

To begin using React Query (TanStack Query) in a React application, you typically install the @tanstack/react-query package and wrap your application with a QueryClientProvider. This provider makes the QueryClient instance available to all components within its tree, allowing them to use hooks like useQuery and useMutation for data fetching.

First, install the necessary package:

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

Next, set up the QueryClientProvider in your application's root file (e.g., src/main.jsx or src/index.jsx) and create a QueryClient instance:

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();

ReactDOM.createRoot(document.getElementById('root')).render(
  
    
      
      {/* Optional: Add React Query Devtools for debugging */}
      
    
  ,
);

Now, you can use the useQuery hook in any component to fetch data. For example, to fetch a list of posts:

import React from 'react';
import { useQuery } from '@tanstack/react-query';

async function fetchPosts() {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts');
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
}

function Posts() {
  const { data, isLoading, isError, error } = useQuery({
    queryKey: ['posts'],
    queryFn: fetchPosts,
  });

  if (isLoading) {
    return <div>Loading posts...</div>;
  }

  if (isError) {
    return <div>Error: {error.message}</div>;
  }

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

export default Posts;

This example demonstrates a basic data fetch. The queryKey (['posts']) is used by React Query to identify and cache the data. The queryFn is the asynchronous function that fetches the data. React Query then provides states like isLoading, isError, and data to manage the UI based on the query's status.