AGENTS.md — TanStack Query (v5)
Conventions for @tanstack/react-query v5. Grounded in the official docs.
- Use the v5 object syntax:
useQuery({ queryKey, queryFn }),useMutation({ mutationFn }). - A query = a unique key + a function returning a promise that resolves data or throws on error.
fetchdoesn't throw on HTTP errors — checkres.okand throw, or the query won't enter the error state.- Query keys are arrays,
JSON.stringify-serializable, and unique to the data:['todos'],['todo', 5, { preview: true }]. - Put every variable the
queryFnuses in the key; changing it refetches automatically. The key is the dependency array. - Object key props are hashed order-independently; array item order matters.
status(pending/error/success) is about data;fetchStatus(fetching/paused/idle) is about the running function. Use both.- Default
staleTimeis0(stale immediately); stale queries refetch on mount, window focus, and reconnect. TunestaleTimeinstead of disabling refetch flags. - Default
gcTimeis 5 minutes for inactive queries. Freshness (staleTime) and retention (gcTime) are independent. - Failed queries retry 3 times with exponential backoff by default — don't disable retries blindly.
- Results are structurally shared (stable references for unchanged data); don't re-memoize
data. - Use
useMutationfor create/update/delete; trigger withmutate(variables). - After a successful mutation,
queryClient.invalidateQueries({ queryKey })(inonSuccess/onSettled) orsetQueryData. - Callback order:
onMutate→onSuccess/onError→onSettled. UsemutateAsynconly when you need to await at the call site. - Don't use TanStack Query for non-server state (form/UI/derived values) — that belongs in
useStateor derived on render.