React Hooks library for remote data fetching
SWR is a React Hooks library created by Vercel that implements the stale-while-revalidate HTTP cache invalidation strategy for data fetching. It returns cached data immediately while fetching fresh data in the background, then updates the UI when new data arrives. This approach provides instant feedback to users while ensuring data freshness without manual cache management.
The library centers around the useSWR hook, which accepts a cache key (typically a URL) and a fetcher function. It automatically handles caching, request deduplication (preventing multiple simultaneous requests for the same resource), revalidation on window focus and network reconnection, and polling intervals. Unlike traditional fetch wrappers, SWR maintains a global cache across components, so multiple instances requesting the same key share a single network request.
With over 7 million weekly downloads, SWR has become a popular choice for data fetching in React applications, particularly in the Next.js ecosystem. It's lightweight at approximately 3-5kB gzipped and supports TypeScript, SSR/SSG, React Suspense, and React Native. The library is transport-agnostic, working with REST APIs, GraphQL, or any async data source.
SWR excels in applications requiring real-time data synchronization, optimistic UI updates, and minimal configuration. It provides advanced features like infinite loading via useSWRInfinite, middleware for custom logic injection, and configurable cache providers. Version 2.x introduced improved TypeScript inference, better error handling, and enhanced middleware capabilities while maintaining backward compatibility.
import useSWR, { SWRConfig } from 'swr';
import { useState } from 'react';
const fetcher = (url) => fetch(url).then(res => {
if (!res.ok) throw new Error('API error');
return res.json();
});
function UserProfile({ userId }) {
const { data, error, isLoading, mutate } = useSWR(
`/api/users/${userId}`,
fetcher,
{ refreshInterval: 30000 }
);
const updateUserName = async (newName) => {
await mutate(
async (currentData) => {
const response = await fetch(`/api/users/${userId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: newName })
});
return response.json();
},
{ optimisticData: { ...data, name: newName }, revalidate: false }
);
};
if (error) return <div>Error: {error.message}</div>;
if (isLoading) return <div>Loading user...</div>;
return (
<div>
<h2>{data.name}</h2>
<p>Email: {data.email}</p>
<button onClick={() => updateUserName('Updated Name')}>
Update Name
</button>
</div>
);
}
function App() {
const [userId, setUserId] = useState(1);
return (
<SWRConfig value={{
revalidateOnFocus: true,
dedupingInterval: 2000,
errorRetryCount: 3
}}>
<UserProfile userId={userId} />
<button onClick={() => setUserId(id => id + 1)}>Next User</button>
</SWRConfig>
);
}
export default App;Real-time dashboards and analytics: Applications displaying frequently updated metrics (stock prices, server status, analytics) benefit from automatic revalidation on focus and configurable polling intervals, ensuring users see current data without manual refresh buttons.
Paginated and infinite scroll lists: The useSWRInfinite hook simplifies implementing Twitter-style infinite feeds or paginated tables by managing page state and loading indicators automatically, with built-in support for cursor-based and offset pagination patterns.
Offline-first applications with optimistic updates: SWR's mutation API enables optimistic UI updates that immediately reflect user actions (like liking a post) while syncing with the backend, automatically reverting changes if the server request fails.
Multi-tab synchronization: When users have the same application open in multiple browser tabs, SWR automatically synchronizes data across tabs through cross-tab revalidation, ensuring consistent state without custom event listeners or polling.
Server-side rendered applications: Next.js and similar frameworks leverage SWR's SSR/SSG support with fallbackData to hydrate pages with initial data from the server, then seamlessly transition to client-side revalidation for dynamic updates without layout shifts.
A simple yet functional GraphQL client.
The official, opinionated, batteries-included toolset for efficient Redux development
Hooks for managing, caching and syncing asynchronous and remote data in React
npm install swrpnpm add swrbun add swr