◐ Shell
clean mode source ↗

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.

Let's chat

Only one thing left to do...