SWR vs RTK Query: Complete Comparison Guide
SWR and RTK Query are both production-grade solutions for managing server state in React, but they represent opposite ends of the philosophy spectrum. SWR is a lightweight, hook-based library from Vercel that implements the stale-while-revalidate (SWR) pattern, prioritizing bundle size and developer simplicity. RTK Query is a comprehensive data-fetching layer built on Redux Toolkit, providing an opinionated, all-in-one solution with automatic cache management, optimistic updates, and deeply integrated DevTools. Choosing between them means understanding their architectural differences, team requirements, and the actual feature set your application needs.
The Fundamental Difference: Philosophy
SWR follows a minimalist philosophy: fetch data as a hook, let the library handle revalidation and deduplication. The mental model is straightforward—your component hooks into data that auto-refreshes intelligently. RTK Query follows an API-centric, normalized-cache model where you define all your endpoints upfront, and the library manages relationships, subscriptions, and mutations orchestrated by Redux. An SWR developer might say, "Why am I configuring Redux when I just want to fetch a list?" An RTK Query developer might counter, "Why rebuild cache invalidation, optimistic updates, and TypeScript inference for every new endpoint?"
Architecture Comparison
SWR runs entirely within React components—no store, no actions, no boilerplate. When you call useSWR(), it immediately begins caching at the hook level. RTK Query follows the Redux pattern: you define an API slice with endpoints, dispatch actions, and reducers manage the store state. SWR's architecture scales to ~200 LOC for a basic app; RTK Query's boilerplate starts at ~150 LOC even for one endpoint, but pays dividends across multiple features.
| Aspect | SWR | RTK Query |
|---|---|---|
| Core dependency | Minimal (one package) | Redux Toolkit required |
| Bundle size (min+gzip) | ~4 KB | ~20 KB |
| Setup boilerplate | ~5 lines (one hook call) | ~50+ lines (API slice) |
| Cache location | In-memory (React context-like) | Redux store |
| Type inference | Manual annotations needed | Automatic from endpoint config |
| Optimistic updates | Manual implementation | Built-in via queryFulfilled |
| Cache invalidation | Request deduplication + revalidation | Normalized tags + subscribers |
| DevTools integration | Basic logging | Full Redux DevTools + time travel |
| Learning curve | Shallow (familiar hook pattern) | Moderate (Redux + generator functions) |
Bundle Size and Performance
SWR's 4 KB footprint is deliberate—it does one thing well. RTK Query's 20 KB reflects its scope: automatic cache normalization, subscription tracking, and optimistic-update orchestration. For a project fetching 50+ unique endpoints, RTK Query's upfront cost amortizes; for a simple todo app, SWR's leanness wins. Real-world data (Bundlephobia, 2026) shows SWR dominates in time-to-interactive for lightweight apps, while RTK Query's normalized cache prevents runtime bloat on data-heavy dashboards.
Developer Experience: Real Example
Building a user list with pagination illustrates the difference:
SWR approach:
const { data, error, isLoading, mutate } = useSWR(
`/api/users?page=${page}`,
fetcher
);
RTK Query approach:
const { data, error, isLoading } = api.useGetUsersQuery({ page });
SWR's strength is familiarity—you recognize the object shape immediately. RTK Query's strength is automation—the API knows the endpoint, transforms, and cache tag automatically.
Mutations and Optimistic Updates
SWR treats mutations as manual imperative calls; you fetch, validate, then call mutate() to revalidate. RTK Query codifies mutation patterns: you define a mutation endpoint, and queryFulfilled hooks let you apply optimistic updates before the server responds.
// SWR mutation
const { mutate } = useSWR('/api/users');
async function addUser(newUser) {
const result = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify(newUser)
});
mutate(); // Revalidate after
}
// RTK Query mutation
const [addUser] = api.useAddUserMutation();
// Mutation automatically invalidates related queries
For simple mutations, SWR is less boilerplate. For complex workflows (optimistic updates + rollback), RTK Query prevents bugs.
TypeScript and Type Safety
Both libraries support TypeScript, but differently. SWR requires manual typing of response shapes; RTK Query generates types from your API definition.
// SWR: you type the response manually
interface User { id: number; name: string; }
const { data } = useSWR<User[]>('/api/users', fetcher);
// RTK Query: types flow from endpoint definition
const { data } = api.useGetUsersQuery(); // Typed automatically
RTK Query's inference is a significant productivity win on large codebases.
When to Choose Each
Choose SWR if:
- You have a small-to-medium app with
<20unique API endpoints - Your team is new to Redux and prefers hooks
- Bundle size is a critical constraint (embedded web, IoT dashboards)
- You value simplicity and familiarity over comprehensive features
Choose RTK Query if:
- Your app has
>30API endpoints with complex relationships - You're already using Redux for state
- You need optimistic updates, rollback, and cache invalidation
- Your team prioritizes type safety and developer ergonomics at scale
TanStack Query (React Query) is the middle ground: lighter than RTK Query (~8 KB), more sophisticated than SWR, and framework-agnostic.
Key Takeaways
- SWR excels at simplicity and bundle size; RTK Query wins on features and type inference
- SWR's stale-while-revalidate pattern automatically refreshes; RTK Query's tags enable granular invalidation
- Both solve real problems; the choice depends on team size, app complexity, and existing stack
- For most new React apps with TypeScript, RTK Query's automation outweighs its boilerplate cost
Frequently Asked Questions
Do I need Redux to use RTK Query?
Yes. RTK Query is a Redux Toolkit add-on, so you must set up Redux (store + Provider). SWR works without Redux, making it ideal for Redux-free projects.
Is SWR production-ready?
Absolutely. SWR powers production apps at Vercel and many enterprise deployments. It's battle-tested for five years and actively maintained.
Can I migrate from SWR to RTK Query later?
Yes, but it requires refactoring: moving hook calls to mutation endpoints, adopting Redux, and rewriting cache logic. For new projects expecting growth, choosing early saves effort.
Does RTK Query support React Server Components?
No. Both SWR and RTK Query are client-side libraries. For Next.js App Router server components, consider simpler approaches or TanStack Query.
What about offline-first caching?
SWR has no built-in offline support. RTK Query's normalized cache can be persisted, but both require third-party solutions (e.g., localforage) for true offline-first UX.