SWR keeps your UI fast and reactive
Fetch data with one hook
Pass a key and a fetcher to useSWR. The hook manages the request, caches the response, and keeps data fresh. You get data, error, and isLoading to drive your UI.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>}Make it reusable
Need the same data in many places? Wrap useSWR in a custom hook once and reuse it across your components. Caching, deduplication, and revalidation are shared automatically.function useUser(id) { const { data, error, isLoading } = useSWR(`/api/user/${id}`, fetcher) return { user: data, isLoading, isError: error }}One request, shared everywhere
Call the same hook in every component that needs the data. Components stay independent, no props get threaded through the tree, and SWR still sends a single request: the key is deduped, cached, and shared.function Content({ userId }) { const { user, isLoading } = useUser(userId) if (isLoading) return <Spinner /> return <h1>Welcome back, {user.name}</h1>}function Avatar({ userId }) { const { user, isLoading } = useUser(userId) if (isLoading) return <Spinner /> return <img src={user.avatar} alt={user.name} />}Fetch, then revalidate
Named for stale-while-revalidate, the cache strategy from HTTP RFC 5861: serve cached data first, revalidate behind it, then update. Repeat views render instantly.
Fast, lightweight, reusable
One hook you can call anywhere, with a small API surface and almost no bundle cost.
Transport and protocol agnostic
Bring your own fetcher: REST, GraphQL, gRPC, or anything that returns a promise.
Built-in cache and deduplication
Components sharing a key issue a single request, cached and shared between them.
Real-time experience
Subscribe to a key and let updates stream in as they arrive.
Revalidation on focus
Switching back to a tab refetches automatically, so stale data never lingers.
Revalidation on reconnect
Coming back online refetches without you wiring up a listener.
Polling on interval
Keep a view current on a timer, and pause it when the tab is hidden.
Pagination and scroll restoration
Paginated and infinite lists keep their position across navigation.
SSR and SSG
Hydrate from server-rendered data and revalidate on the client.
Local mutation
Update optimistically and reconcile against the server response.
Smart error retry
Failed requests back off exponentially instead of hammering the origin.
TypeScript and Suspense
Fully typed from the ground up, and ready for React Suspense and React Native.