This guide is the deep reference for engineers, architects, library maintainers, and contributors. It documents how TanStack Query is built internally: the framework‑agnostic core engine, the per‑framework adapter layer, the caching and state‑machine internals, the monorepo build pipeline, and the security and operational characteristics of the library. Where the User Guide teaches how to use the library, this guide explains how it works and how to maintain it.
1. Executive summary
TanStack Query is a headless, framework‑agnostic async‑state management library distributed as a 27‑package pnpm monorepo. A single core package (@tanstack/query-core) contains all of the caching, retry, network, and observation logic and has zero runtime framework dependency. Each supported framework ships a thin adapter package that binds the core's imperative observer API to that framework's reactivity primitives (React hooks, Vue refs, Solid signals, Svelte stores, Angular signals, Lit controllers).
| Attribute | Value |
|---|---|
| Repository | TanStack/query (analyzed at commit 3270e09) |
| Package version (all packages) | 5.101.0 |
| Published packages | 27 (core, 7 framework adapters, devtools, persistence, eslint plugin, codemods, utilities) |
| Language | TypeScript (strict), ESM + CJS dual output |
| Core dependencies | None at runtime — the core is self‑contained |
| Package manager | pnpm 11 (workspaces) |
| Build orchestration | Nx (affected graph) + tsup per package |
| License | MIT |
The architectural thesis is "one engine, many bindings." All behavior lives in query-core; adapters are deliberately minimal. This is why every concept (query keys, staleTime, mutations, invalidation) behaves identically across frameworks, and why a bug fix or feature in the core lands for all frameworks at once.
┌──────────────────────────────────────────────┐
│ @tanstack/query-core │
│ (framework-agnostic engine — no UI deps) │
│ │
App code ──────► │ QueryClient ── QueryCache ── Query │
(queryFn, │ │ │ │ (state │
mutationFn) │ │ │ │ machine) │
│ │ MutationCache ─ Mutation │
│ │ │
│ Observers: QueryObserver / InfiniteQuery / │
│ QueriesObserver / MutationObserver │
│ │
│ Singletons: focusManager · onlineManager · │
│ notifyManager · timeoutManager │
└───────────────▲────────────────────────────────┘
│ subscribe() / getCurrentResult()
┌────────────┬───────────────┼───────────────┬──────────────┐
react-query vue-query solid-query svelte-query angular-query
(hooks + (composables (createX + (stores + (injectX +
useSync- + refs) signals) $-stores) signals)
ExternalStore)
2. Repository architecture
Layered package inventory
The 27 packages fall into clear responsibility layers. Organizing them by layer (not alphabetically) is the only way to navigate the repo sensibly.
Layer 0 — The engine
| Package | Responsibility |
|---|---|
@tanstack/query-core |
The entire caching/retry/observer engine. Everything else depends on it. |
Layer 1 — Framework adapters (one per host framework)
| Package | Host | Binding mechanism |
|---|---|---|
@tanstack/react-query |
React 18/19 | useSyncExternalStore over observers |
@tanstack/vue-query |
Vue 2.6+/3 | Reactive refs, plugin install |
@tanstack/solid-query |
Solid | Fine‑grained signals; options passed as a function |
@tanstack/svelte-query |
Svelte 5 | Svelte stores / runes |
@tanstack/angular-query-experimental |
Angular 16+ | Signals + DI provider |
@tanstack/lit-query |
Lit | Reactive controllers on LitElement |
@tanstack/preact-query |
Preact | Hooks (mirror of react-query) |
Layer 2 — Devtools (per framework)
@tanstack/query-devtools is the framework‑agnostic devtools UI (a Solid‑built component, the largest single module at ~164 KB). Per‑framework wrappers mount it: @tanstack/react-query-devtools, @tanstack/vue-query-devtools, @tanstack/solid-query-devtools, @tanstack/svelte-query-devtools, @tanstack/preact-query-devtools.
Layer 3 — Persistence
| Package | Responsibility |
|---|---|
@tanstack/query-persist-client-core |
Core persist/restore engine (persistQueryClient, createPersister, retry strategies). |
@tanstack/query-sync-storage-persister |
Persister for sync stores (localStorage, sessionStorage). |
@tanstack/query-async-storage-persister |
Persister for async stores (RN AsyncStorage), with asyncThrottle. |
@tanstack/react-query-persist-client (+ solid/svelte/angular/preact variants) |
PersistQueryClientProvider wiring. |
Layer 4 — Experimental / integration
| Package | Responsibility |
|---|---|
@tanstack/react-query-next-experimental |
Next.js App Router streaming SSR integration. |
@tanstack/query-broadcast-client-experimental |
Sync cache across browser tabs via BroadcastChannel. |
Layer 5 — Tooling
| Package | Responsibility |
|---|---|
@tanstack/eslint-plugin-query |
Lint rules (exhaustive‑deps, stable‑client, property‑order, etc.). |
@tanstack/query-codemods |
jscodeshift codemods for v4→v5 (and v3→v4) migrations. |
@tanstack/query-test-utils |
Internal test helpers. |
Note
examples/(per framework) andintegrations/(bundler/SSR smoke tests likereact-webpack-5,react-next-15,angular-cli-20) are workspace members but are excluded from the publish/build pipeline — they exist only to validate the packages against real toolchains.
The query-core module map
Inside packages/query-core/src/, the engine decomposes into focused modules:
| Module | Class / export | Role |
|---|---|---|
queryClient.ts |
QueryClient |
Public facade. Owns the two caches and default options; exposes the imperative API. |
queryCache.ts |
QueryCache |
A Map<queryHash, Query> with add/remove/find/notify. |
query.ts |
Query |
A single cache entry. Holds state, runs the fetch, reduces actions. |
queryObserver.ts |
QueryObserver |
Bridges a Query to a consumer; computes the result object, manages stale/refetch timers. |
infiniteQueryObserver.ts |
InfiniteQueryObserver |
QueryObserver subclass adding page navigation. |
infiniteQueryBehavior.ts |
infiniteQueryBehavior |
The page‑fetching algorithm injected into a query's fetch. |
queriesObserver.ts |
QueriesObserver |
Manages a dynamic array of QueryObservers and the combine reducer. |
mutationCache.ts / mutation.ts / mutationObserver.ts |
MutationCache / Mutation / MutationObserver |
The mutation counterparts. |
retryer.ts |
createRetryer, CancelledError |
Retry/backoff loop, pause/continue, cancellation. |
removable.ts |
Removable (abstract) |
Garbage‑collection timer base class for Query and Mutation. |
subscribable.ts |
Subscribable |
Observer‑pattern base class for caches, managers, and observers. |
focusManager.ts / onlineManager.ts |
singletons | Window‑focus and online/offline detection. |
notifyManager.ts |
notifyManager |
Batches and schedules listener notifications. |
timeoutManager.ts |
timeoutManager |
Pluggable setTimeout/setInterval backend for stale/gc timers. |
environmentManager.ts |
environmentManager |
Server‑vs‑client detection (overridable). |
hydration.ts |
dehydrate / hydrate |
SSR serialization of cache state. |
streamedQuery.ts |
experimental_streamedQuery |
Build a queryFn from an AsyncIterable. |
thenable.ts |
pendingThenable |
React‑compatible promise with .status/.value/.reason. |
utils.ts |
hashing, matching, skipToken, replaceEqualDeep |
Shared utilities. |
3. Core internals
The observer pattern foundation
Everything reactive in the core extends a tiny Subscribable<TListener> base class. It owns a Set of listeners and exposes subscribe(listener) returning an unsubscribe function, plus protected onSubscribe/onUnsubscribe hooks. QueryCache, MutationCache, FocusManager, OnlineManager, and every observer extend it. This single abstraction is why the entire system is push‑based: a state change cascades through notify() calls to subscribed observers, which recompute and notify their listeners (the framework adapter), which trigger a re‑render.
Query.#dispatch(action)
└─► reducer updates Query.state
└─► notifyManager.batch(...)
├─► each QueryObserver.onQueryUpdate() → updateResult() → notify listener
└─► QueryCache.notify({ type: 'updated', ... }) → cache subscribers (devtools, etc.)
QueryClient — the facade
QueryClient is what application code instantiates. It owns a QueryCache, a MutationCache, the global defaultOptions, and two maps of per‑key defaults (queryDefaults, mutationDefaults). Its surface splits into:
- Imperative cache access:
getQueryData,setQueryData,getQueriesData,setQueriesData,getQueryState. - Cache control:
invalidateQueries,refetchQueries,cancelQueries,removeQueries,resetQueries. - Fetching:
fetchQuery,prefetchQuery,ensureQueryData, and the*InfiniteQueryvariants. - Defaults:
setDefaultOptions,setQueryDefaults,setMutationDefaults, and thedefaultQueryOptions/defaultMutationOptionsresolvers that merge global → per‑key → call‑site options. - Lifecycle:
mount/unmount(reference‑counted; the first mount subscribes to focus/online managers, the last unmount tears them down).
mount() is reference counted via #mountCount: only the first provider subscribes the client to focusManager and onlineManager; only the last unmount() unsubscribes. This is what makes "refetch on focus" and "resume on reconnect" work, and why these listeners are not attached when no provider is mounted.
The Query state machine
A Query (one per unique queryHash) holds a QueryState and mutates it only through a reducer driven by dispatched actions — a Redux‑style state machine.
QueryState fields: data, dataUpdateCount, dataUpdatedAt, error, errorUpdateCount, errorUpdatedAt, fetchFailureCount, fetchFailureReason, fetchMeta, isInvalidated, status (pending/error/success), fetchStatus (fetching/paused/idle).
Reducer actions:
| Action | Effect |
|---|---|
fetch |
Enter fetching (or paused if offline); set pending if no data. |
success |
Store data, bump dataUpdateCount, return to idle. |
error |
Store error, bump counts, set status: 'error', mark isInvalidated. |
failed |
Record a retry failure (fetchFailureCount, fetchFailureReason). |
pause / continue |
Toggle fetchStatus between paused and fetching. |
invalidate |
Set isInvalidated: true (makes the query stale). |
setState |
Merge an arbitrary partial state (used by setQueryData, hydration). |
The fetch() method builds an AbortController, lazily exposes its signal to the queryFn (reading signal flips an internal #abortSignalConsumed flag so the core knows whether to abort on unmount), runs the (optional) behavior.onFetch hook (this is where infinite‑query page logic is injected), then drives a retryer. On success it validates the data is not undefined — otherwise it throws <queryHash> data is undefined.
QueryObserver — the result engine
A QueryObserver is the bridge between a Query and one consumer. useQuery (and the equivalents) create exactly one observer. The observer:
- Subscribes to its
Queryand, ononSubscribe, decides whether to fetch on mount (shouldFetchOnMount). - Computes the result object in
createResult()— derivingisPending/isLoading/isStale/etc. from query state, applyingplaceholderData, runningselect(memoized via reference equality + structural sharing), and trackingselecterrors. - Manages two timers via
timeoutManager: the stale timeout (re‑evaluatesisStalewhenstaleTimeelapses) and the refetch interval (polling). - Implements render optimization through
trackResult(), which wraps the result in aProxy. Only fields the component actually reads are tracked, and the observer re‑notifies only when a tracked field changes (notifyOnChangeProps). This is why accessingdatabut notdataUpdatedAtavoids re‑renders on timestamp churn.
InfiniteQueryObserver extends this, overriding createResult to add fetchNextPage/fetchPreviousPage, hasNextPage/hasPreviousPage, and the directional isFetchingNextPage/isFetchNextPageError flags.
Mutations
Mutations mirror queries but are imperative and short‑lived. A MutationObserver (created by useMutation) builds a fresh Mutation each time mutate() is called. The Mutation.execute() method orchestrates the full callback waterfall in strict order: mutationCache.onMutate → options.onMutate → run mutationFn via the retryer → onSuccess → onSettled (or onError → onSettled on failure), dispatching pending/success/error/pause/continue actions to its own reducer.
MutationCache additionally tracks scopes: mutations sharing a scope.id are serialized via canRun()/runNext() so only one executes at a time and paused ones resume in order.
The manager singletons
Four module‑level singletons coordinate cross‑cutting concerns:
| Singleton | Detects / does | Customizable via |
|---|---|---|
focusManager |
Window focus via visibilitychange. Drives focus refetch. |
setEventListener, setFocused |
onlineManager |
Online/offline via online/offline events. Drives reconnect refetch + mutation resume. |
setEventListener, setOnline |
notifyManager |
Batches listener callbacks into a single tick; integrates with React batching. | setNotifyFunction, setBatchNotifyFunction, setScheduler |
timeoutManager |
Backs all setTimeout/setInterval for stale/gc/refetch timers. |
setTimeoutProvider |
Note
The
focusManagerandonlineManagerguardtypeof window !== 'undefined'so they no‑op in React Native and SSR. Both are overridable, which is how React Native apps wire focus/online detection toAppState/NetInfo.
Garbage collection (Removable)
Query and Mutation both extend the abstract Removable, which manages a gcTime timer. When a query loses its last observer (or a mutation settles with no observers), scheduleGc() starts a timer; if nothing re‑subscribes before it fires, optionalRemove() deletes the entry from its cache. updateGcTime() always keeps the longest requested gcTime and defaults to 5 minutes on the client / Infinity on the server.
The retryer
createRetryer() is a self‑contained loop used by both queries and mutations. It:
- Resolves the
retrypolicy (boolean | number | (failureCount, error) => boolean; default 3 on client, 0 on server) andretryDelay(default exponential backoffmin(1000 × 2^n, 30000)). - Pauses between retries when the document is hidden or the device is offline (
canContinue()), resuming when focus/connectivity returns. - Supports cancellation via
CancelledError(withrevert/silentflags) — the publicisCancelledErrorhelper is deprecated in favor ofinstanceof CancelledError. - Returns a thenable plus
cancel/continue/canStart/start/statuscontrols.
Hydration & SSR serialization
dehydrate(client, options) walks both caches and serializes successful queries (defaultShouldDehydrateQuery) and paused mutations (defaultShouldDehydrateMutation) into a plain { queries, mutations } object. hydrate(client, state) rebuilds cache entries, carefully not overwriting entries that already hold newer data (compares dataUpdatedAt/dehydratedAt).
4. Configuration reference
TanStack Query has no external configuration file — it is a library, configured entirely in code through the QueryClient constructor and per‑query/mutation options. (The only process.env read in the published core is NODE_ENV, used to gate development‑only warnings and error redaction; it is not user configuration.)
QueryClientConfig
new QueryClient({
queryCache?: QueryCache, // supply a custom cache (rare; for global onError/onSuccess)
mutationCache?: MutationCache, // same for mutations
defaultOptions?: {
queries?: QueryObserverOptions, // defaults for every query
mutations?: MutationObserverOptions,
dehydrate?: DehydrateOptions, // SSR serialization defaults
hydrate?: HydrateOptions,
},
})
Global default options (defaultOptions.queries)
These are the cross‑cutting knobs most apps set once. See the User Guide reference for the full option table; the operationally significant ones:
| Option | Default | Operational note |
|---|---|---|
staleTime |
0 |
The single biggest lever on request volume. Raise it app‑wide to cut redundant refetches. |
gcTime |
300000 (5 min) |
Memory footprint of the cache. Infinity on server to survive SSR render. |
retry |
3 (queries), 0 (mutations) |
Set 0 for fail‑fast UIs; a function for status‑code‑aware retries. |
networkMode |
'online' |
Set 'always' for non‑HTTP sources; auto‑'offlineFirst' when a persister is set. |
refetchOnWindowFocus / refetchOnReconnect / refetchOnMount |
true |
Disable globally for low‑traffic or cost‑sensitive backends. |
structuralSharing |
true |
Keeps stable references across refetches; disable only for very large payloads where the diff cost matters. |
Per‑key defaults
setQueryDefaults(queryKey, options) and setMutationDefaults(mutationKey, options) apply defaults to all queries/mutations whose key prefix‑matches. This is the idiomatic way to, e.g., give all ['user', …] queries a longer staleTime without touching call sites.
Customizable internals (advanced)
For specialized environments, the manager singletons accept overrides:
import { focusManager, onlineManager, notifyManager, timeoutManager } from '@tanstack/query-core'
onlineManager.setEventListener((setOnline) => { /* wire to NetInfo */ return cleanup })
notifyManager.setScheduler(requestAnimationFrame) // custom flush scheduling
timeoutManager.setTimeoutProvider(myCoalescingProvider) // for apps with thousands of timers
5. Build system & development workflow
Toolchain
| Concern | Tool |
|---|---|
| Package manager | pnpm 11 with workspaces (pnpm-workspace.yaml) |
| Task orchestration | Nx — nx affected/nx run-many build only what changed in the dependency graph |
| Per‑package bundling | tsup (esbuild‑based), emitting ESM + CJS + .d.ts |
| Type checking | tsc, tested against a matrix of TypeScript 5.4 → 6.0 (devDeps typescript54…typescript60) |
| Unit tests | Vitest (jsdom env, istanbul coverage) |
| Bundle size budget | size-limit (@size-limit/preset-small-lib) |
| Dead‑code/dep hygiene | knip |
| Monorepo dep consistency | sherif (catches version drift across packages) |
| Package publish validation | publint + @arethetypeswrong/cli |
| Linting | ESLint (@tanstack/eslint-config, react‑hooks, cspell) |
| Formatting | Prettier |
| Docs | TypeDoc (@tanstack/typedoc-config) + a link verifier (scripts/verify-links.ts) |
| Releases | Changesets |
Key scripts (root package.json)
pnpm build # nx affected --target=build (excludes examples/integrations)
pnpm build:all # build every package
pnpm dev # watch + rebuild all
pnpm test # = test:ci
pnpm test:ci # nx run-many: sherif, knip, docs, eslint, lib, types, build
pnpm test:lib # vitest unit tests across affected packages
pnpm test:types # type-level tests
pnpm test:size # size-limit budget check
pnpm changeset # author a changeset for the next release
Tip
The CI gate (
test:ci) runs eight target types:sherif(dep consistency),knip(dead code),docs(link integrity),eslint,lib(unit),types(type tests),build, and abuildsmoke. A contributor's PR runs theaffectedsubset, so only packages touched by the change (and their dependents) are exercised.
Release model
Releases are changeset‑driven: each PR that changes published behavior adds a changeset describing the bump. changeset version rolls versions and changelogs; changeset publish pushes to npm. All @tanstack/* packages are versioned in lockstep (every package is 5.101.0 at this commit), so consumers can safely mix, e.g., react-query and react-query-devtools at the same version.
6. Security analysis
TanStack Query is a client‑side data‑management library; it does not open ports, read secrets, or execute remote code. Its security surface is therefore narrow and centers on a few areas worth reviewing in any deployment.
Threat surface
| Area | Consideration | Mitigation in code |
|---|---|---|
| SSR error leakage | Errors from pending queries are serialized into the HTML payload during dehydrate, potentially leaking server‑side error details to the client. |
dehydrate redacts errors by default: defaultShouldRedactErrors returns true, and pending‑query rejections are replaced with a generic Error('redacted') in production (the original is console.error‑logged only in non‑production). Override with shouldRedactErrors. |
| Cache persistence | Persisters write cache data to localStorage/IndexedDB/AsyncStorage — readable by any script on the origin (XSS) and not encrypted. |
Treat persisted data as non‑sensitive. Do not persist auth tokens or PII; scope what is dehydrated with shouldDehydrateQuery. Persist‑client supports buster keys and maxAge to invalidate stale/poisoned caches. |
| Cross‑tab sync | query-broadcast-client-experimental mirrors cache across tabs via BroadcastChannel, same‑origin only. |
Same‑origin scoping by the browser; still avoid broadcasting sensitive data. |
queryFn is your code |
The library never constructs requests; it only runs the function you provide. Injection, auth, and URL‑building are the consumer's responsibility. | N/A — by design. Forward signal to enable request cancellation and avoid resource leaks. |
| Supply chain | The core has zero runtime dependencies, minimizing transitive‑dependency risk. Adapters depend only on query-core + their (peer) host framework. |
Lockstep versioning + publint/arethetypeswrong validation of published artifacts. |
Negative knowledge (what the library does not do)
- It does not read environment variables for configuration (only
NODE_ENVfor dev warnings). - It does not include an HTTP client, retry on its own network stack, or perform authentication.
- It does not encrypt persisted caches.
- It does not automatically retry mutations (default
retry: 0), preventing accidental duplicate writes.
Important
The most common real‑world misconfiguration is persisting sensitive data. Because persisters serialize to plaintext browser storage, audit
shouldDehydrateQueryand ensure auth/PII queries are excluded from anyPersistQueryClientProvider.
7. Code quality & conventions
- Encapsulation via native private fields. Internal state uses ECMAScript
#privatefields (#queryCache,#retryer,#observers), not TypeScriptprivate, giving true runtime privacy. - State machines over ad‑hoc mutation.
QueryandMutationmutate state only through reducers fed by typed action unions, making transitions auditable and testable. - Single base abstractions.
Subscribable(observation) andRemovable(GC) are reused across all stateful classes, keeping behavior consistent. - Framework‑agnostic core, thin adapters. Adapters contain almost no logic — React's
useBaseQueryis ~150 lines that mostly wire an observer touseSyncExternalStore. New frameworks are cheap to add. - Render optimization by default. The
trackResultProxy +notifyOnChangePropsmean components re‑render only on fields they read — a correctness‑preserving performance feature baked into the core. - Pluggable seams.
timeoutManager,notifyManager,focusManager,onlineManager, andenvironmentManagerare all swappable, which is how the library adapts to React Native, tests (React.actintegration), and high‑timer‑count environments without forking. - Strict typing. Heavy use of conditional/inferred generics (e.g. the
useQueriestuple inference,DataTagtyped keys) provides end‑to‑end type safety fromqueryFnreturn throughselectto the component.
8. Testing strategy
| Test type | Tooling | What it covers |
|---|---|---|
| Unit/behavioral | Vitest (jsdom) | Cache logic, observers, retryer, hydration, each adapter's hooks (packages/*/src/__tests__). |
| Type‑level | tsd‑style type tests via test:types |
The complex generic inference (queries tuples, typed keys) across the TS 5.4–6.0 matrix. |
| Bundle size | size-limit | Each package stays within its byte budget — a regression gate, since bundle size is a core selling point. |
| Lint/static | ESLint + cspell + knip | Code style, spelling, dead code. |
| Monorepo integrity | sherif | Dependency version consistency across all 27 packages. |
| Publish artifacts | publint + arethetypeswrong | Validates exports maps, dual ESM/CJS resolution, and .d.ts correctness. |
| Real‑toolchain smoke | integrations/* |
The library installed into real Next.js/webpack/Vite/Angular‑CLI apps. |
Note
A few internal tests around retry cooldowns rely on fake timers; the
timeoutManagerabstraction exists partly to make timer‑dependent behavior deterministically testable.
9. Operations & contributing
Adding a feature to the core
Because all behavior lives in query-core, most features are implemented there and surfaced through adapters only if they need framework‑specific glue (e.g. a new hook). The workflow:
- Implement in
packages/query-core/src, with unit + type tests. - Add a changeset (
pnpm changeset). - If user‑facing in a framework, thread it through the relevant adapter(s) and the
docs/framework/*reference. pnpm test:cimust pass (the full eight‑target gate).
Adding a new framework adapter
Mirror an existing adapter's structure: re‑export @tanstack/query-core, create framework‑idiomatic wrappers around QueryObserver/MutationObserver/QueriesObserver using subscribe() + getCurrentResult(), and provide a client‑provider mechanism. Keep logic out of the adapter — push it into the core.
Versioning & migration
- All packages release in lockstep; pin them to the same version.
- Breaking changes ship as major versions with a codemod (
@tanstack/query-codemods) and ESLint rules to ease migration (e.g. the v5 single‑object‑argument enforcement, surfaced at runtime asBad argument type. Starting with v5, only the "Object" form is allowed…).
Operational tuning checklist
- [ ] Set an app‑wide
staleTimeto control request volume. - [ ] Decide
refetchOnWindowFocus/refetchOnReconnectpolicy per backend cost. - [ ] On SSR, set
gcTime: Infinityserver‑side and verifydehydrateerror redaction. - [ ] If persisting, audit
shouldDehydrateQueryto exclude sensitive data; set a buster key tied to your release. - [ ] Mount exactly one devtools instance and one
QueryClient. - [ ] Enable
@tanstack/eslint-plugin-queryrecommended rules in CI.
10. Quick reference
Public exports of @tanstack/query-core
QueryClient, QueryCache, MutationCache, Query, Mutation, QueryObserver, InfiniteQueryObserver, QueriesObserver, MutationObserver, focusManager, onlineManager, notifyManager, timeoutManager, environmentManager, dehydrate, hydrate, defaultShouldDehydrateQuery, defaultShouldDehydrateMutation, CancelledError, hashKey, matchQuery, matchMutation, partialMatchKey, replaceEqualDeep, keepPreviousData, skipToken, shouldThrowError, isServer, experimental_streamedQuery, plus all types.
Status reference
status |
fetchStatus |
Meaning |
|---|---|---|
pending |
fetching |
First load in flight (isLoading). |
pending |
paused |
Wants to load but offline. |
success |
idle |
Has data, nothing running. |
success |
fetching |
Has data, background refetch in flight (isRefetching). |
error |
idle |
Fetch failed, holds the error. |
Mutation status reference
idle → pending → success | error, surfaced as isIdle/isPending/isSuccess/isError, with reset() to return to idle.
Environment behavior matrix
| Environment | gcTime default |
retry default |
Focus/online listeners |
|---|---|---|---|
| Browser (client) | 5 min | 3 | Active (via window) |
| Server (SSR) | Infinity |
0 | No‑op (no window) |
| React Native | 5 min | 3 | Inactive until wired via setEventListener |