SkillAgentSearch skills...

tanstack-query

TanStack Query v5 (React Query) patterns including queryOptions helper, query key factories, mutations, optimistic updates, infinite queries, Suspense mode, and prefetching

Install / Use

npx skills add PatrickJS/awesome-cursorrules

Installs into whichever agent you are using.

About this skill
📦

Other

Other agent config

Quality Score

91/100

Category

Marketing

Supported Platforms

Cursor

Our assessment of tanstack-query

tanstack-query scores 91/100 on our quality scale, 37th of 127 Marketing skills we index (top 30%).

Its Other is 3.5 KB long, well organised into 9 sections with 7 code examples: a solid amount of guidance for an agent.

With 40,838 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
26/30
Structure
20/20
Description
15/15
Adoption
20/20
Freshness
11/15

Maintenance, license and trust

  • The repository was last updated about 4 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
  • Our last check on 2026-09-24 found the source still online.
  • It is released under the CC0-1.0 license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 98/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.

AI review by kimi-k2.7-code on 2026-09-24. Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

tanstack-query compared with similar skills

All 4 of these similar skills score higher than tanstack-query; compare them before choosing.

SkillScoreStarsUpdatedFormat
tanstack-query (this skill)by PatrickJS9140.8k4mo agoOther
headroomby headroomlabs-ai10073.8ktodayCLAUDE.md
rufloby ruvnet10073.3ktodayCLAUDE.md
javascript-testing-patternsby wshobson10039.9k4d agoSKILL.md
hyperframesby nexu-io10097.9k1d agoSKILL.md

Frequently asked questions

How do I install tanstack-query?
Run npx skills add PatrickJS/awesome-cursorrules. The install tabs above show the steps for each supported agent.
Which AI agents does tanstack-query work with?
It is written for Cursor, as a Other file. Other agents that read the same format can often use it too.
Is tanstack-query safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It is CC0-1.0-licensed and scores 98/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is tanstack-query still maintained?
The repository was last updated about 4 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.

description: "TanStack Query v5 (React Query) patterns including queryOptions helper, query key factories, mutations, optimistic updates, infinite queries, Suspense mode, and prefetching" globs: ["src//*.tsx", "src//.ts", "src/queries/**/"] alwaysApply: false

You are an expert in TanStack Query v5 (React Query), TypeScript, and async state management.

Core Principles

  • TanStack Query manages server state — NOT a general client state manager
  • Every query needs a stable, serializable query key that uniquely describes the data
  • Mutations handle writes; queries handle reads — never blur this boundary
  • Use queryOptions() helper (v5) for reusable, co-located query definitions
  • v5 breaking change: useQuery only accepts options object form — no positional args

QueryClient Setup

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 1000 * 60,
      retry: (count, error: any) => error?.status !== 404 && count < 2,
    },
  },
})

Query Key Factory Pattern

export const postKeys = {
  all: ['posts'] as const,
  lists: () => [...postKeys.all, 'list'] as const,
  list: (filters?: PostFilters) => [...postKeys.lists(), filters] as const,
  details: () => [...postKeys.all, 'detail'] as const,
  detail: (id: string) => [...postKeys.details(), id] as const,
}

queryOptions Helper (v5)

export const postQueryOptions = (id: string) =>
  queryOptions({
    queryKey: postKeys.detail(id),
    queryFn: () => fetchPost(id),
    staleTime: 1000 * 60 * 5,
  })

// In component
const { data } = useQuery(postQueryOptions(postId))

// In router loader
loader: ({ params, context: { queryClient } }) =>
  queryClient.ensureQueryData(postQueryOptions(params.postId))

Mutations

const { mutate, isPending } = useMutation({
  mutationFn: (input: CreatePostInput) => createPost(input),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: postKeys.lists() })
  },
  onError: (error) => toast.error(error.message),
})

Optimistic Updates

const mutation = useMutation({
  mutationFn: updatePost,
  onMutate: async (updated) => {
    await queryClient.cancelQueries({ queryKey: postKeys.detail(updated.id) })
    const previous = queryClient.getQueryData(postKeys.detail(updated.id))
    queryClient.setQueryData(postKeys.detail(updated.id), updated)
    return { previous }
  },
  onError: (_, updated, ctx) => {
    queryClient.setQueryData(postKeys.detail(updated.id), ctx?.previous)
  },
  onSettled: (_, __, updated) => {
    queryClient.invalidateQueries({ queryKey: postKeys.detail(updated.id) })
  },
})

Infinite Queries

const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
  queryKey: postKeys.lists(),
  queryFn: ({ pageParam }) => fetchPosts({ cursor: pageParam }),
  initialPageParam: undefined as string | undefined,
  getNextPageParam: (lastPage) => lastPage.nextCursor,
})
const allPosts = data?.pages.flatMap((p) => p.items) ?? []

Suspense Mode (v5)

// useSuspenseQuery — no isLoading needed, Suspense handles it
const { data } = useSuspenseQuery(postQueryOptions(postId))
// Wrap with <Suspense fallback={<Skeleton />}> + <ErrorBoundary>

Key Rules

  • Always define queryOptions outside components — never inline in useQuery()
  • Never use useEffect to fetch data — use loaders or useQuery
  • Use placeholderData: keepPreviousData for pagination to avoid layout shifts
  • Instantiate QueryClient once at app root — never inside a component

Related Skills

View on GitHub
GitHub Stars40.8k
CategoryMarketing
Updated3mo ago
Forks3.5k

Languages

JavaScript

Trust signals

98/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 info