Overview

Use TanStack Query when an app has mutations, optimistic updates, paginated or infinite lists, or complex invalidation; use SWR when the app mostly reads and the one-hook API is enough. As of 2026-10-01 TanStack Query is at v5.104 and SWR at 2.5. Both cache server state; neither replaces a client-state store (zustand-vs-redux).

Comparison

DimensionTanStack Query v5SWR 2
Core APIuseQuery({ queryKey, queryFn }), useMutationuseSWR(key, fetcher), useSWRMutation
KeysArrays with structural matching; invalidateQueries({ queryKey }) by prefixKey string, array, or function; mutate(key)
MutationsLifecycle (onMutate, onError, onSettled) and rollback patternuseSWRMutation and mutate with optimisticData
PaginationuseInfiniteQuery, prefetchQuery, enabled for dependent queriesuseSWRInfinite, conditional keys
Suspense and RSCuseSuspenseQuery; prefetch on the server and hydrateSuspense option; fewer documented server patterns
FrameworksReact, Vue, Solid, Svelte, Angular (experimental package)React
Size (gzipped, whole package)About 14 KBAbout 6 KB

Pick TanStack Query when

Pick TanStack Query for apps where writes and cache coordination matter.

  • Mutations that invalidate or update several queries, with optimistic UI and rollback.
  • Infinite scroll, prefetching, dependent queries, and cache persistence.
  • Query devtools to inspect cache state and staleness.
  • The same model across React, Vue, Solid, or Svelte.
  • Define reusable queryOptions objects so keys and functions stay together.

Pick SWR when

Pick SWR when the app is small and read-heavy.

  • A dashboard or content page with a few GET endpoints and few writes.
  • Revalidate on focus and reconnect, and stale-while-revalidate behavior, with minimal setup.
  • You prefer one small hook over a configured client.

Server Components first

Do not add either library for data a Server Component can fetch; see server-vs-client-components. Add a client cache only for interactive, frequently changing, or user-driven data.

Migrate

SWR to TanStack Query: replace useSWR(key, fetcher) with useQuery({ queryKey, queryFn }) and mutate(key) with queryClient.invalidateQueries({ queryKey }). Migrate mutation-heavy screens first, since reads on SWR keep working; the libraries coexist. Moving the other way is only worth it for bundle size on a small app. See react-state-management for state strategy.

FAQ

Should I use TanStack Query or SWR?

Use TanStack Query v5 when the app has mutations, optimistic updates, infinite lists, or complex invalidation. Use SWR 2 for small read-mostly apps where the one-hook API is enough.

Is SWR smaller than TanStack Query?

Yes; SWR is about 6 KB gzipped for the whole package, against about 14 KB for TanStack Query. Moving from TanStack Query to SWR is only worth it for bundle size on a small app.

Do I need TanStack Query with React Server Components?

Not for data a Server Component can fetch. Add a client cache only for interactive, frequently changing, or user-driven data.

Can TanStack Query replace Redux or Zustand?

No; both libraries cache server state, and neither replaces a client-state store. See zustand-vs-redux for client state.