TanStack Query in a Next.js SaaS boilerplate
The API keys screen kept its own useState copy of a list the server had already loaded. Create and delete updated that copy by hand.
NextBento is still a Next.js 16 SaaS boilerplate: Supabase, Stripe, Resend, $59 one-time. TanStack Query is the client cache for lists that change after first paint. It is not a second framework. Pricing is the same. Setup is still the quick start.
Server Components still paint the page
Next.js lets a Server Component await fetch, or a database client, and render the result. Those docs also say credentials and query logic stay out of the client bundle, because that work runs on the server. (Fetching data)
I left the API keys page on that path. The server reads api_keys for the signed-in user and passes a stripped list into the client as initialData. The full token is not in that payload. The route that creates a key still checks the session and the subscription before it inserts a row.
Onboarding is the other client read. The wizard calls /api/onboarding after the page is up. That payload is a name and a couple of flags, and it changes when you save.
Query owns the list after the first paint
TanStack's overview treats server state as a different problem from component state. It lives somewhere else, you fetch it asynchronously, other people can change it, and the copy in the browser goes stale. (Query overview)
useQuery holds the API key rows. Create and delete go through useMutation, then invalidate ['api-keys']. The one-time full key from a create stays in React state on that screen so you can copy it. It is not written into the query cache. A later refetch only has key_last4.
The onboarding load is useQuery on ['onboarding']. Saving the profile or finishing the wizard invalidates that key. Login, signup, and password reset stay single fetch calls. They are not lists you reopen.
The browser gets one QueryClient. The server builds a new one per request. A module-level client would leak one user's cache into the next request. TanStack's SPA sample creates the client at module scope. That sample is not an App Router server.
The file that matters is the key list
The same Next.js guide says client components can use a library like SWR or React Query when the cache belongs in the browser. (Fetching data)
In this repo that contract is lib/query/keys.ts. Two keys today: ['api-keys'] and ['onboarding']. Agents are told not to add TanStack Router or TanStack Start, and not to replace react-hook-form. Tables were already on TanStack Table v8. The grids did not need a second library.
If you want to leave Next.js for TanStack Start, this kit is not that. Start is a different app, with its own router.
The library map is which TanStack libraries fit Next.js. The definition is what is TanStack.