Skip to content

raf-query is early. The API can still change between minor releases, so use it at your own risk.

raf-query

Reference

API reference

Every export of @raf-query/react and @raf-query/core, QueryClient's members, query options and their defaults.

QueryClient

const const queryClient: QueryClient<never>queryClient = new new QueryClient<never>(config?: QueryClientConfig<never>): QueryClient<never>QueryClient(const config: QueryClientConfig<never> | undefinedconfig);
MemberUse
new QueryClient(config?)config.defaults, config.onError, config.isServer, config.layer, config.throwOnError (Effect reads; default false with a layer) (typed errors)
prefetch(factory, input)Start a query; returns a QueryHandle. Starting queries
ensure(factory, input, options?)fetch, but stale data resolves at once; returns Promise<QueryHandleWithData>
fetch(factory, input, options?)Wait for fresh data; returns Promise<QueryHandleWithData>
invalidate(factory, input) / invalidate(filter)Mark stale and refetch read queries. Query invalidation
setData(factory, input, updater)Write data. Mutations
getData(factory, input)Cached data, or undefined. Query functions
reset(factory, input) / reset(filter)Drop data and errors; read queries suspend and refetch. Resolves when they settle
remove(factory, input) / remove(filter)Remove entries and abort their requests
effectThe Effect QueryCache behind the client
runPromise(effect)Run an Effect with QueryCache and the layer's services, for loaders and actions. Typed errors
subscribe(listener)Cache events: added, updated, observers (a reader subscribed or left), removed, and failed (with the error)
isFetching(filter?)How many entries have a request in flight, optionally only those matching { queryKey, exact? }
getAll(), getQuery(factory, input?)Cache entries, for devtools and integrations
clear()Drop every entry and abort in-flight requests
mount()Start window-focus and reconnect refetching. The providers call it
isServerDetected from window. Server clients don't retry, never gc, skip stale timers, and never revalidate cached data
dispose()Interrupt every request and release the layer's services. Resolves when its finalizers have run

ensure and fetch take { pages: n } as a third argument for paged factories, to load more than the first page.

Query options

Accepted by queryOptions, infiniteQueryOptions and config.defaults (all but throwOnError, which is per query):

OptionDefault
queryKeyRequired. Query keys
queryFnRequired. Query functions
staleTime0 ms
gcTime5 minutes; Infinity on the server
retry (count, boolean, predicate, Schedule)3; 0 on the server
retryDelay (ms, or a function of the failure count)Doubling from 1 s, at most 30 s
refetchOnWindowFocus, refetchOnReconnecttrue (only read, stale queries refetch)
structuralSharing (keep deeply equal parts of data)true
enabled (false: the query doesn't run, such as on the server)true
metaNone
throwOnError (Effect reads: reject, or false for a Result; a read's own wins)The client's (typed errors)

infiniteQueryOptions also takes initialPageParam, getNextPageParam, getPreviousPageParam and maxPages. Infinite queries

useQuery

const [const promise: Thenable<Post>promise, 
const controls: QueryControls<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>>
controls
] =
useQuery<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>, undefined>(factory: (input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>, handle: QueryHandle<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>>, options?: (Options & {
    readonly throwOnError?: never;
} & {
    readonly throwOnError?: undefined;
}) | undefined): readonly [promise: Thenable<Post>, controls: QueryControls<...>] (+1 overload)
useQuery
(
const factory: (input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>
factory
,
const handle: QueryHandle<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>>
handle
, const options: Options | undefinedoptions);
const [const data: Postdata,
const dataControls: QueryControls<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>>
dataControls
] =
useQuery<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>, undefined>(factory: (input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>, handle: QueryHandleWithData<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>>, options?: (Options & {
    readonly throwOnError?: never;
} & {
    readonly throwOnError?: undefined;
}) | undefined): readonly [data: Post, controls: QueryControls<...>] (+1 overload)
useQuery
(
const factory: (input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>
factory
,
const handleWithData: QueryHandleWithData<(input: {
    slug: string;
}) => QueryOptions<Flat<{
    data: Post;
    key: readonly ["post", string];
}>>>
handleWithData
, const options: Options | undefinedoptions);

Options: whilePending ("suspend" or "previous"), refetchInterval, refetchOnWindowFocus, refetchOnReconnect.

ControlMeaning
isPendingNo data yet for the handle's input; use(promise) will suspend
isPreviousThe promise holds data for a previous input while the handle's input loads
isFetchingA request is in flight: first load, new input, or background refetch
isStaleData is older than staleTime
errorError from a failed background refetch. Existing data stays readable
updatedAtWhen the data in the promise was fetched
key, inputKey and input of the data in the promise. They differ from the handle's while isPrevious
hashStable string form of the handle's key, for key props on Suspense boundaries
refetch()Refetch now. Returns a promise, so it can be awaited inside a transition or action

Paged factories add fetchNextPage(), fetchPreviousPage(), hasNextPage, hasPreviousPage, isFetchingNextPage and isFetchingPreviousPage. See Reading queries.

The promise is a Thenable<Data>: read its status, value and reason to render without Suspense, like TanStack Query's data. See Reading without Suspense.

@raf-query/react

Everything from @raf-query/core, plus:

ExportUse
HydrationBoundaryWrites server data into the client: a loader's state, or in server components the request's client. React Server Components · React Router
QueryClientProviderProvides a client to the tree
QueryProviderProvider for React Server Components apps: a client per server render and per browser tab; its server render starts no request. React Server Components
useQueryClient()Read the client
useQuery(factory, handle, options?)[Thenable<Data>, controls], or [Data, controls] for a QueryHandleWithData; Effect queryFns with throwOnError: false (the call's, else the query's, else the client's: default with a layer) yield Result<Data, ErrorOf> instead. Paged: Data is { pages, pageParams }
useWaterfall(factory, input)Start a query during render and return its handle. Request waterfalls
useIsFetching(filter?)Global in-flight count (compatibility). Prefer router pending + per-query isFetching. Background fetching indicators

Subpath entries:

EntryUse
@raf-query/react/tanstack-routersetupRouterIntegration. TanStack Start
@raf-query/react/devtoolsQueryDevtools, QueryDevtoolsPanel. Devtools

@raf-query/core

Framework-agnostic: the Promise QueryClient and the Effect cache behind it.

ExportUse
QueryClientThe cache with Promise methods (above)
allKeyed(record)Await a record of promises, keeping keys
dehydrate(client) / hydrate(client, state)Low-level cache transfer used by the integrations
QueryCacheThe cache service (qc.effect): make, layer, and the verbs as Effects
QueryCache entries: Query.fetch, Query.changes, Query.getUnsafe, Query.metaUnsafe, …
QueryObserverOne reader's view of a query, with tracked results; for bindings
PlatformThe page the cache watches (focus, network); swap it in tests
queryOptions(options)Typed options for a query factory
infiniteQueryOptions(options)Typed options for a paged query factory
hashKey(key), matchesKey(key, prefix)Key helpers
canDehydrate(query)The default dehydrate filter: entries with data or a request in flight
Query.CancelledErrorFailure of an Effect request whose entry was removed before it settled. Promise verbs reject with an AbortError instead
Query.DisabledErrorWhy a query with enabled: false has no data: ensure / fetch fail with it, and on a server its promise rejects with it
RedactedErrorWhat a streamed pending query rejects with when its server request failed
QueryHandle<TFactory>Handle type for props fed by prefetch: { key, input }
QueryHandleWithData<TFactory>What ensure and fetch return: a QueryHandle plus the data they waited for
Thenable<T>Promise with status / value / reason, read by use() or without Suspense
QueryOptions, InfiniteQueryOptions, InfiniteDataTyped by a bag: QueryOptions<{ data: Post }>. Effect queryFns add error and services; key is the key's shape
DataOf<TFactory>, InputOf<TFactory>, ErrorOf<TFactory>A factory's data, input and error types
ServicesOf<TFactory>The services a factory's queryFn Effect needs; never for promises
Register, QueryMetaAugment Register with queryMeta to type meta