TanStack Query
Server-state manager
TanStackQuery
Stop syncing server data by hand.
Query gives async data a cache, a lifecycle, and a set of declarative APIs for fetching, sharing, refetching, mutating, and observing server state across TypeScript applications.
00.0 MillionTotal Downloads000,000,000Weekly Downloads0GitHub Stars
The server-state standard for modern frontend apps.
Server-state cache
freshness, retries, gc, dedupe
Mutation workflow
optimistic UI, rollback, invalidate
Framework adapters
React, Vue, Solid, Svelte, Angular, Lit
Why Query
Server state is not the same problem as client state.
Server data is remote, shared, cached, refetched, invalidated, and sometimes stale on purpose. Query handles that lifecycle directly instead of making you recreate it with reducers, effects, and synchronized stores.
Important defaults do the boring work.
Caching, request dedupe, retries, background refetching, window-focus updates, and garbage collection are already wired for the shape of real apps.
Query keys become the cache contract.
Keys describe the resource, inputs, filters, and scope so reads, writes, invalidation, prefetching, and devtools all speak the same language.
Mutations have a real lifecycle.
Handle pending UI, optimistic writes, invalidation, rollback, and follow-up refetches without inventing an ad hoc client-state machine.
Devtools make the cache visible.
See query keys, observers, freshness, retries, errors, mutations, and cache contents while the app is actually running.
1
Fetch
A query function resolves data or throws. Query owns retry, cancellation, and deduping.
2
Share
Every observer reads the same cache entry instead of refetching from every component.
3
Revalidate
Stale data can stay on screen while a background refetch quietly refreshes it.
4
Collect
Unused data sticks around long enough to feel instant, then garbage collection cleans up.
queryKey: ['projects', filters]
queryFn: fetchProjects
staleTime: 30_000
gcTime: 300_000
Cache lifecycle
Keep data useful while the network catches up.
Query lets stale data remain valuable. Screens can render instantly from cache, refetch in the background, keep previous results during pagination, and recover when the user comes back online.
Mutations
Writes update the world, then the cache.
Query keeps mutation work explicit: optimistic updates, pending states, error recovery, invalidation, and background reconciliation are first-class instead of scattered through components.
1optimistic write
setQueryData(['todos'], next)
2server mutation
await saveTodo(todo)
3targeted refresh
invalidateQueries({ queryKey: ['todos'] })
4rollback path
onError: restoreSnapshot
Result: the UI can feel instant, the server remains the source of truth, and the cache knows exactly what changed.
Framework adapters
One server-state model, every UI runtime.
The core cache model travels across frameworks. Teams can keep the same query keys, invalidation strategy, mutation semantics, and mental model whether the UI is React, Vue, Solid, Svelte, Angular, Preact, or Lit.
ReactVueSolidSvelteAngularPreactLit
Field notes
Query is the default answer for async server state.
The original copy was right: Query saves code by deleting whole categories of hand-written fetching, loading, retry, cache, and mutation logic.
Open source ecosystem
Maintainers, education, sponsors, and partners keep Query moving.
Query is built in public and taught in public. The maintainers, partner integrations, Query.gg, and GitHub sponsors all stay close to the product story.
Maintainers
Partners
Query You?
We're looking for
TanStack Query
Partners to join our mission! Partner with us to push the boundaries of
TanStack Query
and build amazing things together.
Only one thing left to do...