swr vs react-query vs axios-hooks
React Data Fetching and Server State Management
swrreact-queryaxios-hooksSimilar Packages:

React Data Fetching and Server State Management

axios-hooks, react-query, and swr are libraries designed to handle data fetching and server state in React applications. axios-hooks is a specialized wrapper that binds the Axios HTTP client directly to React hooks, simplifying request execution but coupling logic to Axios. react-query (now evolved into TanStack Query) provides a powerful framework for managing asynchronous server state, offering robust caching, background updates, and mutation tools independent of the HTTP client. swr (Stale-While-Revalidate) is a lightweight React Hook library for data fetching that focuses on speed and simplicity, automatically handling caching, revalidation, and focus detection with a minimal API surface.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
swr10,065,23532,368310 kB1952 months agoMIT
react-query1,520,61749,3262.26 MB1613 years agoMIT
axios-hooks48,6521,89847.1 kB6a year agoMIT

React Data Fetching: axios-hooks vs React Query vs SWR

When building modern React applications, managing server state is one of the most common challenges. Developers often move from basic useEffect fetching to specialized libraries to handle caching, loading states, and errors. axios-hooks, react-query, and swr offer different approaches to this problem. Let's compare how they handle real-world engineering scenarios.

🏗️ Core Philosophy: Wrapper vs. State Manager

axios-hooks acts as a direct bridge between Axios and React.

  • It wraps Axios instances into hooks.
  • Best for teams standardizing on Axios who want less boilerplate.
  • Tightly couples your components to the Axios library.
// axios-hooks: Direct Axios binding
import useAxios from 'axios-hooks';

function UserProfile() {
  const { data, loading, error } = useAxios('/api/users/1');
  if (loading) return <p>Loading...</p>;
  return <div>{data.name}</div>;
}

react-query treats server data as a separate state category.

  • It manages caching, synchronization, and updates independently.
  • Works with any HTTP client (fetch, axios, graphql).
  • Requires more setup but offers greater control.
// react-query: Server state management
import { useQuery } from '@tanstack/react-query';

function UserProfile() {
  const { data, isLoading, error } = useQuery({
    queryKey: ['user', 1],
    queryFn: () => fetch('/api/users/1').then(res => res.json())
  });
  if (isLoading) return <p>Loading...</p>;
  return <div>{data.name}</div>;
}

swr focuses on the stale-while-revalidate strategy.

  • It returns cached data immediately while fetching fresh data in the background.
  • Extremely minimal configuration for basic use cases.
  • Built by Vercel with Next.js integration in mind.
// swr: Stale-while-revalidate
import useSWR from 'swr';

function UserProfile() {
  const { data, error, isLoading } = useSWR('/api/users/1', fetcher);
  if (isLoading) return <p>Loading...</p>;
  return <div>{data.name}</div>;
}

🔄 Caching and Revalidation Strategies

axios-hooks caches based on request configuration.

  • Identical config objects return cached promises.
  • Less flexible for complex invalidation scenarios.
  • Manual control required for refetching.
// axios-hooks: Config-based caching
const { data } = useAxios({
  url: '/api/posts',
  method: 'GET'
});
// Same config returns cached result automatically

react-query uses query keys for precise cache control.

  • You can invalidate specific queries by key.
  • Supports background refetching on window focus.
  • Highly configurable stale times.
// react-query: Key-based caching
const { data } = useQuery({
  queryKey: ['posts'],
  queryFn: getPosts,
  staleTime: 1000 * 60 * 5 // 5 minutes
});
// queryClient.invalidateQueries(['posts']) triggers refetch

swr revalidates automatically on focus or reconnect.

  • Default behavior is to show stale data then update.
  • Simple API for manual revalidation.
  • Great for real-time feel without websockets.
// swr: Auto-revalidation
const { data, mutate } = useSWR('/api/posts', fetcher);
// Automatically revalidates when window regains focus
// mutate() manually triggers revalidation

✏️ Handling Mutations (POST/PUT/DELETE)

axios-hooks uses a manual trigger hook.

  • Separates read and write operations clearly.
  • Requires managing loading state manually.
  • Less built-in support for optimistic updates.
// axios-hooks: Manual mutation
import useAxios from 'axios-hooks';

function EditForm() {
  const [{ loading }, execute] = useAxios(
    { url: '/api/users/1', method: 'PUT' },
    { manual: true }
  );
  return <button onClick={() => execute()}>Save</button>;
}

react-query provides a dedicated mutation hook.

  • Includes callbacks for success, error, and settlement.
  • Supports optimistic updates out of the box.
  • Integrates with query invalidation automatically.
// react-query: Dedicated mutation hook
import { useMutation, useQueryClient } from '@tanstack/react-query';

function EditForm() {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: updateUser,
    onSuccess: () => queryClient.invalidateQueries(['users'])
  });
  return <button onClick={() => mutation.mutate()}>Save</button>;
}

swr offers a mutation hook or helper.

  • useSWRMutation is available for complex cases.
  • Simple mutate function for basic updates.
  • Optimistic updates require manual cache manipulation.
// swr: Mutation helper
import useSWRMutation from 'swr/mutation';

function EditForm() {
  const { trigger } = useSWRMutation('/api/users/1', sendPutRequest);
  return <button onClick={() => trigger()}>Save</button>;
}

📦 Package Status and Maintenance

axios-hooks is stable but niche.

  • Not deprecated, but development pace is slower.
  • Tied to Axios ecosystem updates.
  • Suitable for legacy Axios-heavy codebases.
// axios-hooks: Import structure
import useAxios from 'axios-hooks';
// No major namespace changes recently

react-query has migrated to TanStack.

  • The react-query npm package is legacy (v3).
  • New projects should use @tanstack/react-query (v4/v5).
  • Active maintenance with frequent updates.
// react-query: Modern import
import { useQuery } from '@tanstack/react-query';
// Old 'react-query' package is no longer recommended

swr is actively maintained by Vercel.

  • Stable API with incremental improvements.
  • Strong integration with Next.js features.
  • Regular security and performance patches.
// swr: Standard import
import useSWR from 'swr';
// Consistent API across recent versions

🌐 Similarities: Shared Ground

While the differences are clear, all three libraries aim to simplify data fetching in React. Here are key overlaps:

1. ⚛️ Hook-Based API

  • All three use React Hooks for component logic.
  • Encourage functional component patterns.
  • Manage loading and error states internally.
// All packages use similar hook patterns
const { data, loading, error } = useLibrary(...);

2. 🔄 Automatic Loading States

  • Provide boolean flags for UI feedback.
  • Reduce boilerplate compared to useState.
  • Standardize error handling across components.
// Common pattern across all three
if (loading) return <Spinner />;
if (error) return <ErrorMessage />;

3. 🛡️ Error Handling

  • Capture HTTP errors automatically.
  • Expose error objects to components.
  • Allow retry logic configuration.
// All expose error objects
const { error } = useLibrary(...);
console.error(error.message);

📊 Summary: Key Differences

Featureaxios-hooksreact-queryswr
Primary FocusAxios WrapperServer State ManagerData Fetching Hook
HTTP ClientAxios OnlyAny (Fetch, Axios, etc.)Any (Fetch, Axios, etc.)
CachingRequest Config BasedQuery Key BasedURL/Key Based
MutationsManual ExecuteDedicated useMutationuseSWRMutation
MaintenanceStable / NicheActive (TanStack)Active (Vercel)
Learning CurveLowMediumLow

💡 The Big Picture

axios-hooks is like a specialized adapter 🔌 — it connects Axios directly to your UI. Use it if you are locked into Axios and want minimal setup for simple GET requests without introducing a larger library.

react-query (TanStack Query) is like a command center 🎛️ — it gives you full control over server state, caching, and synchronization. Use it for complex dashboards, enterprise apps, or when you need robust mutation handling and cache invalidation.

swr is like a streamlined dashboard 🚀 — it gets you up and running fast with smart defaults. Use it for content sites, Next.js projects, or when you want automatic revalidation without heavy configuration.

Final Thought: For most new professional projects, react-query (TanStack) or swr are the safer long-term bets due to their flexibility and active maintenance. Reserve axios-hooks for specific scenarios where Axios coupling is already a decided standard and complexity is low.

How to Choose: swr vs react-query vs axios-hooks

  • swr:

    Choose swr if you prioritize simplicity and speed with a focus on the stale-while-revalidate strategy. It is perfect for projects that need automatic revalidation on focus or reconnect, lightweight implementation, and a minimal learning curve without sacrificing essential caching features.

  • react-query:

    Choose react-query (specifically the modern @tanstack/react-query version) if you need enterprise-grade features like complex caching, optimistic updates, and pagination support. It is ideal for large-scale applications where server state management is critical and you want flexibility to switch HTTP clients without refetching logic.

  • axios-hooks:

    Choose axios-hooks if your project is already heavily invested in Axios and you need a quick way to bind requests to components without setting up a broader state management system. It is best suited for smaller applications where tight coupling to Axios is not a concern and advanced caching strategies are not required.

README for swr

SWR


Introduction

SWR is a React Hooks library for data fetching.

The name “SWR” is derived from stale-while-revalidate, a cache invalidation strategy popularized by HTTP RFC 5861. SWR first returns the data from cache (stale), then sends the request (revalidate), and finally comes with the up-to-date data again.

With just one hook, you can significantly simplify the data fetching logic in your project. And it also covered in all aspects of speed, correctness, and stability to help you build better experiences:

  • Fast, lightweight and reusable data fetching
  • Transport and protocol agnostic
  • Built-in cache and request deduplication
  • Real-time experience
  • Revalidation on focus
  • Revalidation on network recovery
  • Polling
  • Pagination and scroll position recovery
  • SSR and SSG
  • Local mutation (Optimistic UI)
  • Built-in smart error retry
  • TypeScript
  • React Suspense
  • React Native

...and a lot more.

With SWR, components will get a stream of data updates constantly and automatically. Thus, the UI will be always fast and reactive.


View full documentation and examples on swr.vercel.app.


Quick Start

import useSWR from 'swr'

function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)

  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

In this example, the React Hook useSWR accepts a key and a fetcher function. The key is a unique identifier of the request, normally the URL of the API. And the fetcher accepts key as its parameter and returns the data asynchronously.

useSWR also returns 3 values: data, isLoading and error. When the request (fetcher) is not yet finished, data will be undefined and isLoading will be true. When we get a response, it sets data and error based on the result of fetcher, isLoading to false and rerenders the component.

Note that fetcher can be any asynchronous function, you can use your favourite data-fetching library to handle that part.


View full documentation and examples on swr.vercel.app.


Authors

This library is created by the team behind Next.js, with contributions from our community:

Contributors

Thanks to Ryan Chen for providing the awesome swr npm package name!


License

The MIT License.