# Tanstack Query

TanStack Query v5 data fetching patterns including useSuspenseQuery, useQuery...

- Repository: https://github.com/Kiranism/next-shadcn-dashboard-starter (7212 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add Kiranism/next-shadcn-dashboard-starter --skill tanstack-query -g -a claude-code -y`
Codex: `npx skills add Kiranism/next-shadcn-dashboard-starter --skill tanstack-query -g -a codex -y`
Cursor: `npx skills add Kiranism/next-shadcn-dashboard-starter --skill tanstack-query -g -a cursor -y`
Gemini CLI: `npx skills add Kiranism/next-shadcn-dashboard-starter --skill tanstack-query -g -a gemini-cli -y`

## Description

TanStack Query v5 data fetching patterns including useSuspenseQuery, useQuery, mutations, cache management, and API service integration. Use when fetching data, managing server state, or working with TanStack Query hooks.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# TanStack Query Patterns

## Purpose

Modern data fetching with TanStack Query v5 (latest: 5.90.5, November 2025), emphasizing Suspense-based queries, cache-first strategies, and centralized API services.

**Note**: v5 (released October 2023) has breaking changes from v4:

- `isLoading` → `isPending` for status
- `cacheTime` → `gcTime` (garbage collection time)
- React 18.0+ required
- Callbacks removed from useQuery (onError, onSuccess, onSettled)
- `keepPreviousData` replaced with `placeholderData` function

## When to Use This Skill

- Fetching data with TanStack Query
- Using useSuspenseQuery or useQuery
- Managing mutations
- Cache invalidation and updates
- API service patterns

---

## Quick Start

### Primary Pattern: useSuspenseQuery

For **all new components**, use `useSuspenseQuery`:

```typescript
import { useSuspenseQuery } from '@tanstack/react-query';
import { postsApi } from '~/features/posts/api/postsApi';

function PostList() {
  const { data: posts } = useSuspenseQuery({
    queryKey: ['posts'],
    queryFn: postsApi.getAll,
  });

  return (
    <div>
      {posts.map(post => (
        <PostCard key={post.id} post={post} />
      ))}
    </div>
  );
}

// Wrap with Suspense
<Suspense fallback={<PostsSkeleton />}>
  <PostList />
</Suspense>
```

**Benefits:**

- No `isLoading` checks needed
- Integrates with Suspense boundaries
- Cleaner component code
- Consistent loading UX

---

## useSuspenseQuery Patterns

### Basic Usage

```typescript
const { data } = useSuspenseQuery({
  queryKey: ['user', userId],
  queryFn: () => userApi.get(userId),
});

// data is never undefined - guaranteed by Suspense
return <div>{data.name}</div>;
```

### With Parameters

```typescript
function UserPosts({ userId }: { userId: string }) {
  const { data: posts } = useSuspenseQuery({
    queryKey: ['users', userId, 'posts'],
    queryFn: () => postsApi.getByUser(userId),
  });

  return <div>{posts.length} posts</div>;
}
```

### Dependent Queries

The rest: https://github.com/Kiranism/next-shadcn-dashboard-starter/blob/HEAD/.agents/skills/tanstack-query/SKILL.md
