home / skills / yuniorglez / gemini-elite-core / tanstack-query-expert

tanstack-query-expert skill

/skills/tanstack-query-expert

This skill helps you optimize TanStack Query v5 integrations with React 19 and Next.js 16 by mastering server state, hydration, and caching.

npx playbooks add skill yuniorglez/gemini-elite-core --skill tanstack-query-expert

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
5.3 KB
---
name: tanstack-query-expert
description: Senior Server State Architect for TanStack Query v5 (2026). Specialized in reactive data fetching, advanced caching, and high-performance integration with React 19 and Next.js 16. Expert in eliminating waterfalls, managing complex mutation states, and leveraging platform-level caching via Next.js `"use cache"` and Partial Prerendering (PPR).
---

# πŸ“‘ Skill: tanstack-query-expert (v1.0.0)

## Executive Summary
Senior Server State Architect for TanStack Query v5 (2026). Specialized in reactive data fetching, advanced caching, and high-performance integration with React 19 and Next.js 16. Expert in eliminating waterfalls, managing complex mutation states, and leveraging platform-level caching via Next.js `"use cache"` and Partial Prerendering (PPR).

---

## πŸ“‹ The Conductor's Protocol

1.  **Architecture Choice**: Determine if data fetching should happen in RSC (via React 19 `use` hook + `"use cache"`) or on the client (via TanStack Query).
2.  **Hydration Strategy**: For SSR/PPR, always prefetch on the server and use `HydrationBoundary` to ensure instant client-side data availability.
3.  **Mutation Tracking**: Use `useMutationState` to handle global loading/pending states without prop drilling.
4.  **Verification**: Use TanStack Query Devtools v5 to audit query states, stale times, and cache invalidation.

---

## πŸ› οΈ Mandatory Protocols (2026 Standards)

### 1. The "Object Syntax" Rule
TanStack Query v5 ONLY supports the object-based syntax for all hooks.
- **Rule**: Never use the deprecated positional argument syntax (e.g., `useQuery(key, fn)`).
- **Correct**: `useQuery({ queryKey: [...], queryFn: ... })`.

### 2. React 19 & Next.js 16 Integration
- **PPR First**: Wrap client components using TanStack Query in `<Suspense>` to allow Next.js 16 to stream content while serving the static shell.
- **"use cache" Directive**: For server-side prefetching, utilize Next.js 16's `"use cache"` to cache the prefetch results at the platform level.
- **Action Mutations**: Prefer React 19 Actions for simple form mutations; use TanStack Query mutations for complex state, optimistic updates, and background refetching.

### 3. Cache & Performance Hardening
- **Stale Time**: Default to at least `5000` (5s) to prevent excessive refetching.
- **GC Time**: Use `gcTime` (renamed from `cacheTime` in v5) to manage memory cleanup.
- **Query Keys**: Always use stable, array-based query keys. Treat keys as unique identifiers for your data.

---

## πŸš€ Show, Don't Just Tell (Implementation Patterns)

### Quick Start: Modern Query with Suspense (React 19)
```tsx
"use client";

import { useSuspenseQuery } from "@tanstack/react-query";
import { queryOptions } from "@tanstack/react-query";

// Pattern: Reusable Query Options
export const userOptions = (id: string) => queryOptions({
  queryKey: ["users", id],
  queryFn: async () => {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new Error("Failed to fetch");
    return res.json();
  },
  staleTime: 1000 * 60 * 5, // 5 min
});

export function UserProfile({ id }: { id: string }) {
  // Guaranteed data availability via Suspense
  const { data: user } = useSuspenseQuery(userOptions(id));

  return <div>Welcome, {user.name}</div>;
}
```

### Advanced Pattern: Global Mutation Tracking
```tsx
import { useMutationState } from "@tanstack/react-query";

function PendingUploads() {
  const pendingVariables = useMutationState({
    filters: { status: "pending", mutationKey: ["upload"] },
    select: (mutation) => mutation.state.variables as { fileName: string },
  });

  return (
    <ul>
      {pendingVariables.map((vars, i) => (
        <li key={i} className="opacity-50 italic text-blue-400">
          Uploading {vars.fileName}...
        </li>
      ))}
    </ul>
  );
}
```

---

## πŸ›‘οΈ The Do Not List (Anti-Patterns)

1.  **DO NOT** use `onSuccess`, `onError`, or `onSettled` in `useQuery`. They are removed in v5. Use `useEffect` or move logic to `queryFn`.
2.  **DO NOT** ignore `isPending`. It replaced `isLoading` in v5 for "no data yet" states.
3.  **DO NOT** use `useQuery` without a `queryKey`. It's the only way to manage the cache effectively.
4.  **DO NOT** forget to `await` prefetchQuery on the server. Non-awaited prefetches lead to hydration mismatches.
5.  **DO NOT** use `enabled` with `useSuspenseQuery`. It's incompatible with the guarantee of data presence.

---

## πŸ“‚ Progressive Disclosure (Deep Dives)

- **[v5 Migration & Breaking Changes](./references/migration.md)**: Moving from v4 to v5 safely.
- **[Next.js 16 SSR & Hydration](./references/ssr-hydration.md)**: Prefetching, `HydrationBoundary`, and `"use cache"`.
- **[Advanced Mutations & Optimistic UI](./references/mutations.md)**: useMutationState and simplified v5 patterns.
- **[Performance & Infinite Queries](./references/performance-infinite.md)**: maxPages and bi-directional pagination.

---

## πŸ› οΈ Specialized Tools & Scripts

- `scripts/audit-query-keys.ts`: Checks for non-array query keys or unstable key generation.
- `scripts/generate-query-hook.py`: Boilerplate generator for v5 query/mutation pairs.

---

## πŸŽ“ Learning Resources
- [TanStack Query Docs](https://tanstack.com/query/latest)
- [TkDodo's Blog (Maintainer)](https://tkdodo.eu/blog/)
- [React 19 Data Fetching Guide](https://react.dev/reference/react/use)

---
*Updated: January 23, 2026 - 16:45*

Overview

This skill packages senior-level best practices for TanStack Query v5 (2026) focused on reactive data fetching, advanced caching, and high-performance integration with React 19 and Next.js 16. It codifies architecture decisions, hydration strategies, mutation tracking, and platform-level caching patterns to eliminate waterfalls and reduce client-server churn. Designed for teams shipping ambitious, data-heavy React apps with PPR and server-driven caching.

How this skill works

The skill inspects your data-flow surface and prescribes whether to fetch on the server (RSC with React 19 use + "use cache") or on the client with TanStack Query hooks. It enforces object-syntax query usage, recommends prefetch+hyrdation patterns (HydrationBoundary), and provides mutation-tracking patterns like useMutationState. It also prescribes cache tuning (staleTime, gcTime) and query-key hygiene to improve cache correctness and performance.

When to use it

  • Building React 19 apps that combine server components and client components with Next.js 16 PPR.
  • Prefetching data on the server to avoid client waterfalls and ensure instant client hydration.
  • Managing complex mutation lifecycles, optimistic updates, and global pending states.
  • Hardening cache behavior for high-throughput UI where excessive refetching leads to perf regressions.
  • Auditing or migrating a codebase to TanStack Query v5 object-syntax and new lifecycle semantics.

Best practices

  • Always use object-based hook syntax: useQuery({ queryKey, queryFn, ... }).
  • Prefetch on the server and wrap client components with Suspense + HydrationBoundary for instant data availability.
  • Use React 19 Actions for simple mutations; use TanStack Query mutations and useMutationState for complex state and optimistic flows.
  • Default staleTime to at least 5000ms and configure gcTime to control memory retention.
  • Use stable, array-based query keys and avoid inline unstable key generation.
  • Avoid onSuccess/onError/onSettled in useQuery; move side effects to useEffect or the queryFn in v5.

Example use cases

  • Next.js 16 page that prefetches user data on the server with "use cache" and hydrates the client for instant profile rendering.
  • A file upload dashboard that shows global pending uploads using useMutationState to list pending variables.
  • Migrating a large app from v4 to v5 by converting positional hooks to object syntax and auditing query keys with provided scripts.
  • Implementing optimistic edits with background refetching and gcTime tuning to keep memory bounded.
  • Streaming PPR shells with client-query components suspended for selective hydration and minimal waterfalling.

FAQ

Should I ever use positional arguments in v5 hooks?

No. v5 requires object-based syntax for all hooks; positional argument patterns are deprecated and unsupported.

When should I prefer server prefetching over client queries?

Prefer server prefetching for critical data needed for first paint or to avoid multiple client fetches; use client queries for interactive or frequently changing data.