React Query vs SWR: Key Differences and When to Use Each
React Query and SWR are popular React libraries for data fetching and caching. React Query offers more built-in features like mutations and query invalidation, while SWR is simpler and focuses on fast, lightweight caching with revalidation.Quick Comparison
Here is a quick side-by-side look at key aspects of React Query and SWR.
| Feature | React Query | SWR |
|---|---|---|
| Primary focus | Data fetching, caching, mutations, query invalidation | Data fetching and caching with revalidation |
| API complexity | More extensive API with hooks for queries, mutations, and cache control | Simpler API focused on useSWR hook |
| Mutations support | Built-in support for mutations (POST, PUT, DELETE) | No built-in mutation support; requires manual handling |
| Cache management | Advanced cache control and invalidation | Automatic cache revalidation on focus and interval |
| Community and ecosystem | Larger community, more plugins and integrations | Smaller but growing community, lightweight |
| Bundle size | Larger due to features (~20KB gzipped) | Smaller and lighter (~3KB gzipped) |
Key Differences
React Query is a full-featured data fetching library designed to handle complex server state management in React apps. It provides hooks not only for fetching data but also for mutations, cache invalidation, and background updates. This makes it ideal for apps that need to modify server data and keep UI in sync automatically.
SWR focuses on simplicity and speed. It uses a single hook useSWR for fetching and caching data with automatic revalidation on window focus or network reconnect. It does not include built-in mutation support, so you handle data changes manually. This makes SWR great for read-heavy apps or simple data fetching needs.
In terms of API, React Query has more concepts and options, which can be powerful but require learning. SWR offers a minimal API that is easy to pick up quickly. Both libraries use caching and background revalidation but differ in cache control and mutation handling.
Code Comparison
Here is how you fetch data from an API endpoint using React Query.
import { useQuery } from '@tanstack/react-query'; function Users() { const { data, error, isLoading } = useQuery(['users'], () => fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json()) ); if (isLoading) return <p>Loading...</p>; if (error) return <p>Error loading users</p>; return ( <ul> {data.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
SWR Equivalent
Here is the same data fetching example using SWR.
import useSWR from 'swr'; const fetcher = url => fetch(url).then(res => res.json()); function Users() { const { data, error } = useSWR('https://jsonplaceholder.typicode.com/users', fetcher); if (!data) return <p>Loading...</p>; if (error) return <p>Error loading users</p>; return ( <ul> {data.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
When to Use Which
Choose React Query when your app needs advanced server state management, including mutations, cache invalidation, and background updates. It is best for complex apps that modify data and require fine control over caching and synchronization.
Choose SWR when you want a lightweight, simple solution for fetching and caching data with automatic revalidation. It fits well for read-only or simple data fetching needs where minimal setup and bundle size matter.