new Query(options)

  • key: hashed cache key
  • fetch(queryKey, signal?): runs the query function with { signal, queryKey }
  • isStale(lastUpdated): compares an entry timestamp against staleTime
const query = new Query({
  queryKey: ['user', userId] as const,
  queryFn: ({ signal, queryKey: [, id] }) => fetchUser(id, signal)
});

query.key; // hashed cache key
await query.fetch(['user', userId] as const);

new QueryClient(options?)

  • staleTime: default stale time in milliseconds
  • hashKey: optional key hasher (default JSON.stringify)
  • persist: optional; requires a persister with get/set/del/clear
  • persist.hydrate: optional function that receives persisted value and returns a Promise
  • persist.dehydrate: optional function receiving queryKey and resolved query value; returning undefined skips save
  • staleTime and hashKey become static defaults for new queries
  • custom hashKey should preserve prefixes if you want invalidateQueries

createQuery(() => options)

  • Creates a reactive query returning a PromiseLike<T> with queryKey and pending
  • Tracks key changes from reactive state and updates cache automatically
  • Uses hydratable internally for SSR and hydration reuse
<script lang="ts">
const productsQuery = queryClient.createQuery(() => ({
  queryKey: ['products', filters],
  queryFn: ({ signal, queryKey: [, currentFilters] }) => fetchProducts(currentFilters, signal)
}));
</script>

<ul style:opacity={productsQuery.pending ? 0.4 : 1}>
  {#each (await productsQuery).items as item (item.name)}
    <li>{item.name}</li>
  {/each}
</ul>

fetchQuery(options)

  • Fetches data and populates cache
  • Refetches only when stale or missing
const user = await queryClient.fetchQuery({
  queryKey: ['user', userId],
  queryFn: ({ signal, queryKey: [, id] }) => fetchUser(id, signal)
});

ensureQuery(options)

  • Ensures a cache entry exists without checking staleness
const postsPromise = queryClient.ensureQuery({
  queryKey: ['posts', userId],
  queryFn: ({ signal, queryKey: [, id] }) => fetchPosts(id, signal)
});

setQuery(queryKey, value)

  • Seeds cache with either a plain value or a Promise
queryClient.setQuery(['user', userId], {
  id: userId,
  name: 'Optimistic value'
});

getQuery(queryKey)

  • Returns the cached Promise, or undefined if not present
const cached = await queryClient.getQuery<{ id: string; name: string }>([
  'user',
  userId
]);

removeQuery(query)

  • Removes a single cache entry using a constructed Query instance
const query = new Query({
  queryKey: ['user', userId],
  queryFn: ({ signal }) => fetchUser(userId, signal)
});

queryClient.removeQuery(query);

invalidateQuery(queryKey)

  • Exact invalidation by key
  • invalidateQueries(prefix?): prefix-based invalidation; omit argument to invalidate everything
queryClient.invalidateQuery(['user', userId]);
queryClient.invalidateQueries(['users']);
queryClient.invalidateQueries();

clear()

  • Clears the entire in-memory query cache
queryClient.clear();

queryOptions(options)

  • Preserves literal queryKey types and propagates them into queryFn
const userQuery = queryOptions({
  queryKey: ['user', userId] as const,
  queryFn: ({ queryKey: [, id], signal }) => fetchUser(id, signal)
});

const user = await queryClient.fetchQuery(userQuery);