TanStack is a collection of headless, framework-agnostic libraries for building modern web applications with full TypeScript support. Born from React Query, TanStack now spans data fetching (Query), a reactive local-first data layer (DB), routing (Router), tables (Table), forms (Form), virtualization (Virtual), and full-stack development (Start, which reached a stable v1 in late 2025). Each library is designed to handle complex UI patterns while remaining completely unstyled: you control the markup and styling. The ecosystem's strength lies in type safety everywhere: route params, query keys, form state, and table columns all enjoy deep inference, catching errors at compile time rather than runtime.
What This Cheat Sheet Covers
This topic spans 15 focused tables and 108 indexed concepts, 83 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: TanStack Query Core Concepts
TanStack Query (formerly React Query) manages server state by treating it separately from client state, handling caching, background refetching, and staleness automatically without global state management.
| Concept | Example | Description | |
|---|---|---|---|
useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) | β’ Fetches and caches data β’ returns data, isLoading, isError, and refetchβ’ automatically refetches when component mounts if data is stale | ||
['todos', { status: 'done', userId: 1 }] | β’ Array uniquely identifying query β’ used for caching and invalidation β’ must be serializable β’ nested objects are fine but order matters | ||
async () => { const res = await fetch('/api/todos'); return res.json() } | β’ Async function returning data or throwing error β’ receives queryKey and signal for cancellationβ’ must return serializable data | ||
useQuery({ queryKey: ['user'], queryFn: getUser, staleTime: 60000 }) | β’ Duration (ms) data is considered fresh β’ defaults to 0 (instantly stale)β’ while fresh, query won't refetch in background | ||
useQuery({ ..., gcTime: 300000 }) | β’ Garbage collection time (ms) β’ inactive queries removed after this duration β’ defaults to 5 minutes β’ renamed from cacheTime in v5 | ||
useQuery({ ..., refetchInterval: 5000 }) | β’ Polling interval (ms) β’ refetches query at fixed intervals β’ stops when window loses focus unless refetchIntervalInBackground: true | ||
useQuery({ queryKey: ['user', id], queryFn: getUser, enabled: !!id }) | β’ Boolean controlling whether query runs β’ dependent queries wait until enabled is trueβ’ query stays in idle status when disabled |