React Query vs SWR: Feature-Rich Data Sync vs Lightweight React Caching
| GitHub stars | — | — |
| npm weekly downloads | — | — |
| Bundle size (gzip) | — | — |
| License | — | — |
| Language | — | — |
Choose React Query if
Choose React Query if your application requires advanced mutation handling (optimistic updates, rollback, retry strategies), built-in pagination/infinite query support, fine-grained cache configuration, and centralized query invalidation across nested or distributed components.
Choose SWR if
Choose SWR if you prioritize minimal bundle impact (~4.5 kB gzipped), zero-config revalidation on focus/network recovery, lightweight React-centric hooks, and simpler use cases where manual mutation side effects and custom pagination logic are acceptable.
React Query excels for complex, mutation-heavy applications requiring robust pagination, optimistic updates, and multi-layered cache management; SWR prioritizes simplicity, minimal bundle size, and intuitive revalidation for straightforward data fetching needs.
Bottom Line
React Query and SWR both solve client-side data fetching and caching in React, but they diverge significantly in scope and philosophy. React Query is a full-featured, opinionated data synchronization framework with deep mutation integration and declarative pagination. SWR is a lean, composable hook library focused on correctness, simplicity, and seamless revalidation—ideal for teams valuing ergonomics and bundle efficiency over out-of-the-box complexity.
Comparison
| Dimension | React Query | SWR |
|---|---|---|
| Bundle Size (gzipped) | ~11.5 kB (@tanstack/react-query v5) | ~4.5 kB (swr v2.2+) |
| Mutations | First-class: useMutation with onMutate, onSettled, rollback, optimistic updates, automatic invalidation |
Mutation support via mutate() helper; no built-in optimistic update or rollback—requires manual state management |
| Pagination / Infinite Queries | Native: useInfiniteQuery, fetchNextPage, hasNextPage, isFetchingNextPage, automatic cursor/state management |
No built-in infinite query API; pagination must be implemented manually using useSWR + key composition and mutate |
| Cache Management | Fully configurable: time-based TTL, GC, stale-while-revalidate, query dependencies, selective prefetching, queryClient methods |
Simpler cache model: per-key TTL (revalidateIfStale, revalidateOnFocus), limited eviction control; relies on key stability |
| Revalidation Triggers | Configurable: focus, network reconnect, interval, manual refetch/invalidateQueries |
Automatic: focus, network reconnect, visibility change; also supports polling and manual mutate |
| Type Safety | Excellent TypeScript support with generic hooks, inferred query keys, and utility types | Strong TypeScript support, especially with useSWR generics and SWRConfig |
| Dev Tools | Official, rich Devtools extension with real-time cache inspection, query history, and mutation tracing | No official Devtools; limited debugging via console logging or custom middleware |
| Learning Curve | Moderate–steep: concepts like query keys, stale time, cache time, and invalidation require understanding | Low: intuitive hook signature (useSWR(key, fetcher)), minimal config, familiar React patterns |
When to Use Each
Use React Query when building data-intensive applications—such as dashboards, admin panels, or collaborative tools—where consistent mutation feedback, offline resilience, complex pagination, and predictable cache behavior are critical. Its ecosystem (e.g., TanStack Router integration, createQueryClient) scales well with large teams and evolving requirements.
Use SWR when shipping lightweight apps (e.g., marketing sites, internal tools, static-first SPAs), when adopting incrementally into an existing codebase, or when team familiarity with React hooks outweighs the need for advanced sync features. Its “stale-while-revalidate” model aligns closely with HTTP semantics and works exceptionally well with server-rendered or edge-cached APIs.
Recommendation
Neither library is objectively superior—selection depends on project constraints and architectural goals. React Query offers more power at the cost of added conceptual overhead and bundle weight; SWR delivers elegance and speed for common patterns without abstraction tax. Evaluate based on whether your app’s data flow demands orchestration (favor React Query) or simplicity (favor SWR).