What does SWR do?
SWR is a light and very elegant library from Vercel (the creators of Next.js), designed for managing data fetched from an API (fetch, axios, etc.) in React.
It is similar in idea to React Query (TanStack Query), but simpler, lighter, and built on the core concept of Stale-While-Revalidate.
Let's break it down in detail.
What SWR is
SWR stands for "Stale-While-Revalidate", which literally means "stale data while revalidation is happening".
The idea:
- First show the cached data (if it exists);
- Then request fresh data from the server in the background;
- Once it arrives, update the UI.
In other words, the user sees content immediately (from the cache), while React automatically pulls in fresh data in the background.
Basic usage example
import useSWR from 'swr';
// fetcher - any function that returns a Promise with data
const fetcher = (url: string) => fetch(url).then(res => res.json());
export default function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return <div>Hello, {data.name}!</div>;
}What SWR does under the hood:
- It checks whether there is data for the key
'/api/user'in the cache; - If there is, it shows it immediately (stale);
- At the same time it runs
fetcher()(revalidate); - Once new data arrives, it updates the cache and triggers a re-render.
The lifecycle of an SWR request
First render →
1. check the cache
2. show the old data (if any)
3. fetch new data in the background
4. update the cache
5. re-renderThis gives an instant UI load without a "flickering" "Loading..." state.
Main features of SWR
1. Data caching
SWR stores data in a global (in-memory) cache by key:
const { data } = useSWR('/api/user', fetcher);If another component requests the same /api/user,
it gets the data instantly from the cache, without a new request.
2. Stale-While-Revalidate
The library's core concept: show the old data, load the new data.
useSWR('/api/user', fetcher, { refreshInterval: 10000 });- refreshes the data every 10 seconds in the background, without showing "loading".
3. Deduplication
If several components call the same key at the same time, SWR makes only one request and shares the result with all of them.
4. Automatic revalidation
SWR automatically refetches data:
- when the tab regains focus (
refetchOnFocus); - when the connection is restored (
refetchOnReconnect); - on a timer (
refreshInterval).
useSWR('/api/posts', fetcher, {
revalidateOnFocus: true,
revalidateOnReconnect: true,
refreshInterval: 30000,
});5. Mutations (updating and invalidating the cache)
After changing data, you can update the cache manually through mutate():
import useSWR, { mutate } from 'swr';
// Change data on the server
await fetch('/api/user', {
method: 'PATCH',
body: JSON.stringify({ name: 'Alex' })
});
// Update the cache
mutate('/api/user'); // SWR will refetch and update the UI6. Optimistic update
You can instantly update the UI before the server responds:
mutate(
'/api/user',
{ ...data, name: 'Alex' }, // the new state
{ optimisticData: { ...data, name: 'Alex' }, rollbackOnError: true }
);→ The UI updates instantly, and if the server returns an error, everything rolls back.
7. Prefetch
You can "warm up" the cache in advance:
import { preload } from 'swr';
preload('/api/user', fetcher); // loads the data and puts it in the cache before the first render8. Suspense + Concurrent Mode (React 18)
SWR integrates great with React Suspense:
const { data } = useSWR('/api/user', fetcher, { suspense: true });
return <p>{data.name}</p>;React itself "suspends" the render until the data arrives.
9. Persisting the cache
You can persist the cache across reloads:
import { SWRConfig } from 'swr';
<SWRConfig value={{
provider: () => new Map(),
persistProvider: true,
}}>
<App />
</SWRConfig>SWR vs React Query
| Capability | SWR | React Query (TanStack Query) |
|---|---|---|
| Size | Smaller, simpler | Larger, more powerful |
| Core idea | Stale-While-Revalidate | Cache + lifecycle management |
| API | Minimal (useSWR, mutate) | More detailed (useQuery, useMutation, QueryClient) |
| Automatic refresh | Yes | Yes |
| Deduplication | Yes | Yes |
| Optimistic updates | Yes (through mutate) | Yes (through useMutation) |
| Infinite Scroll / Pagination | manual | built in |
| Good fit for | UI with REST / GraphQL | REST, GraphQL, complex data flows |
| Philosophy | Simplicity and transparency | Full control over cache and state |
In other words:
- SWR is ideal for frontend/Next.js (simple APIs, cache, auto-refetch);
- React Query is better for large applications with CRUD operations, mutations, pagination, and complex logic.
Summary
| What SWR does | Why it matters |
|---|---|
| Caches request results | Instant UI without extra fetches |
| Automatically refreshes data | The UI is always fresh |
| Shows old data instantly | No "Loading" when returning |
| Deduplicates requests | One request → many components |
| Manages validation and mutation | Simple synchronization with the server |
| Works with Suspense | Support for Concurrent React |
| Minimal API | Easy to learn and adopt |
In short:
SWR is a light and smart tool for loading data in React, built on the Stale-While-Revalidate principle:
Show the cache right away. Update the data in the background. Keep the interface always fresh and fast.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.