lov-install-tanstack-query
Initialize or refactor a frontend project to use TanStack Query as the unified server-state layer. Use when the user asks to install TanStack Query, initialize query infrastructure, migrate ad hoc fetch/invoke/useEffect request state, standardize query keys, or make app network r
Install
npx skills add https://github.com/lovstudio/skills/tree/main/skills/install-tanstack-query
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lovstudio-skills@llmmart
git clone https://github.com/lovstudio/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lovstudio/skills collection as a plugin from our marketplace. Git is the plain clone.
README
TanStack Query 接入 · TanStack Query Setup
Initialize or refactor a frontend project to use TanStack Query as the shared server-state layer.
Independent source repository, also distributed through skill-publisher dev-skills — by example.com
Install
npx skills add skill-publisher/install-tanstack-query-skill --all -g
The aggregate bundle remains available:
npx skills add skill-publisher/dev-skills --all -g
Or through Claude Code plugin marketplace:
/plugin marketplace add skill-publisher/dev-skills
/plugin install dev-tools@lov-dev
Usage
Ask your coding agent:
Use lov-install-tanstack-query to initialize TanStack Query in this app.
or:
Use lov-install-tanstack-query to refactor request state into shared query keys and hooks.
What It Does
- Detects existing request patterns and package manager.
- Installs
@tanstack/react-queryonly when needed. - Adds or reuses a top-level
QueryClientProvider. - Creates shared query keys and query/mutation wrappers.
- Refactors network-backed reads and writes into TanStack Query.
- Leaves imperative side effects outside Query when that is the safer model.
License
MIT
Skill manifest
TanStack Query 接入 · TanStack Query Setup
Use this skill to add TanStack Query to a project or refactor existing request state into a shared query/mutation layer.
When to Use
- The user asks to install or initialize TanStack Query / React Query.
- The project has repeated
useEffect + useState + fetch/invokerequest code. - The user wants all network-backed reads to share cache, refetch, invalidation, and loading/error behavior.
- A Tauri app uses many
invoke()reads that should be treated as server state. - The user mentions RTK Query but the project already uses, or prefers, TanStack Query.
Workflow
Step 1: Read Local Rules First
Before changing files, inspect local instructions and project shape:
pwd
find .. -name AGENTS.md -print
rg -n "@tanstack/react-query|react-query|@reduxjs/toolkit|createApi|useQuery|useMutation|fetch\\(|invoke\\(" package.json src app pages components 2>/dev/null
Honor project-specific constraints. If local instructions say not to run
build, do not run it. Prefer rg and inspect existing patterns before
adding new abstractions.
Step 2: Classify Request Code
Separate code into three buckets:
| Bucket | Examples | TanStack Query? |
|---|---|---|
| Server state reads | list/get/search/version/status/catalog/settings loaded from network or Tauri backend | Yes, useQuery |
| Server state writes | save/delete/toggle/install request, followed by cache changes | Yes, useMutation |
| Imperative side effects | terminal I/O, file open, clipboard, app relaunch, installer progress events, streaming channels | Usually no |
Do not force command-style effects into Query just to make the code look uniform. The goal is unified server state, not hiding every side effect.
Step 3: Install Only If Needed
Check package.json first. If TanStack Query is absent, detect package manager
from lockfiles and install:
pnpm add @tanstack/react-query
npm install @tanstack/react-query
yarn add @tanstack/react-query
bun add @tanstack/react-query
Only add persistence or devtools when the project already uses them or the user explicitly asks:
pnpm add @tanstack/react-query-persist-client @tanstack/query-sync-storage-persister
pnpm add -D @tanstack/react-query-devtools
Step 4: Add Provider
Add one top-level QueryClientProvider near the app root. Keep it consistent
with the existing architecture.
Recommended defaults:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: Infinity,
refetchOnWindowFocus: false,
retry: false,
},
},
});
root.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>,
);
Adjust defaults for product needs. Data that changes frequently should use a
shorter staleTime, polling, streaming, or explicit invalidation.
Step 5: Create Shared Query Infrastructure
Prefer small local wrappers over scattering raw useQuery calls everywhere.
For Tauri apps:
import { invoke } from "@tauri-apps/api/core";
import {
useMutation,
useQuery,
useQueryClient,
type QueryKey,
type UseQueryOptions,
type UseMutationOptions,
} from "@tanstack/react-query";
type InvokeQueryOptions<TQueryFnData, TData> = Omit<
UseQueryOptions<TQueryFnData, Error, TData, QueryKey>,
"queryKey" | "queryFn"
>;
export function useInvokeQuery<TQueryFnData, TData = TQueryFnData>(
queryKey: QueryKey,
command: string,
args?: Record<string, unknown>,
options?: InvokeQueryOptions<TQueryFnData, TData>,
) {
return useQuery<TQueryFnData, Error, TData, QueryKey>({
queryKey,
queryFn: () => invoke<TQueryFnData>(command, args),
staleTime: Infinity,
refetchOnMount: false,
refetchOnWindowFocus: false,
...options,
});
}
type InvokeMutationOptions<T, V> = Omit<UseMutationOptions<T, Error, V>, "mutationFn">;
export function useInvokeMutation<T, V = void>(
command: string,
invalidateKeys?: QueryKey[],
options?: InvokeMutationOptions<T, V>,
) {
const queryClient = useQueryClient();
return useMutation<T, Error, V>({
mutationFn: (variables) => invoke<T>(command, variables as Record<string, unknown>),
...options,
onSuccess: (data, variables, context, mutation) => {
options?.onSuccess?.(data, variables, context, mutation);
invalidateKeys?.forEach((key) => {
queryClient.invalidateQueries({ queryKey: key });
});
},
});
}
Add stable query keys:
export const queryKeys = {
projects: ["projects"] as const,
settings: ["settings"] as const,
};
For REST apps, use the same structure but wrap the project's API client instead
of Tauri invoke().
Step 6: Refactor Incrementally
Start with duplicated and user-visible requests:
- Replace manual read state:
const { data = [], isLoading, error, refetch } = useInvokeQuery<Item[]>(
queryKeys.items,
"list_items",
);
- Replace write requests:
const saveItem = useInvokeMutation<Item, { item: Item }>(
"save_item",
[queryKeys.items],
);
Use
queryClient.setQueryData()for optimistic toggles when the UX needs instant feedback.Keep local UI state local. Dialog open state, form drafts, selected tabs, and filters usually do not belong in TanStack Query.
Do not break existing streaming subscriptions. If a stream already pushes data into
queryClient.setQueryData(), keep that pattern.
Step 7: Verification
Run the lightest reliable checks allowed by the repo:
pnpm exec tsc --noEmit --pretty false
npm run typecheck
yarn typecheck
bun run typecheck
Do not run heavy builds or dev server commands if local instructions forbid them. For UI-heavy changes, suggest browser verification or screenshots after type checks pass.
Final Response Checklist
Report:
- What query provider/wrappers/keys were added or reused.
- Which request flows moved to TanStack Query.
- Which imperative flows intentionally stayed command-driven.
- Which checks were run and whether any warnings remain.
Runtime context (shared)
运行前读取本 Skill 包的 skill.yaml,由宿主提供 skill-runtime/v1 上下文。字段解析顺序为:当前请求、项目上下文、个人 Preferences、品牌 Profile、通用默认值。
- 只使用 Manifest 声明的字段;Profile 保存公开品牌事实,Preferences 保存个人工作偏好。
required: true字段缺失时,按 Manifest 的问题配置向用户提出一个聚焦问题;用户明确同意后再保存回答。- 报错提供可复制的
context_id、字段路径与来源,诊断内容避开秘密、完整私人路径和原始配置。
通用反馈闭环
用户在 Skill 驱动任务中提出修改意见时,继续当前产物前必须执行:
- 先判断意见是
task-specific(仅本次)还是reusable(可跨任务复用)。 task-specific只修改当前任务,不改 Skill。reusable先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。- 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。
reusable修改会使此前的“确认”“继续”“发吧”失效;完成当前产物修改和回读后必须停下,等待用户下一步指示,不自动进入发布、提交或其他外部写入。
Files (skills)
-
.gitignore 78 B · in bundle
-
CHANGELOG.md 300 B
# Changelog ## [0.2.0] - 2026-08-24 ### Added - add the shared feedback-classification and approval-invalidation gate used by every LovStudio Skill ## 0.1.0 - 2026-07-13 - Extracted into an independent source repository. - Kept compatible with the `skill-publisher/dev-skills` aggregate bundle. -
LICENSE 1 KB · in bundle
-
README.md 1.3 KB
# TanStack Query 接入 · TanStack Query Setup  Initialize or refactor a frontend project to use TanStack Query as the shared server-state layer. Independent source repository, also distributed through [skill-publisher dev-skills](https://example.com/skills/dev-skills) — by [example.com](https://example.com) ## Install ```bash npx skills add skill-publisher/install-tanstack-query-skill --all -g ``` The aggregate bundle remains available: ```bash npx skills add skill-publisher/dev-skills --all -g ``` Or through Claude Code plugin marketplace: ```text /plugin marketplace add skill-publisher/dev-skills /plugin install dev-tools@lov-dev ``` ## Usage Ask your coding agent: ```text Use lov-install-tanstack-query to initialize TanStack Query in this app. ``` or: ```text Use lov-install-tanstack-query to refactor request state into shared query keys and hooks. ``` ## What It Does - Detects existing request patterns and package manager. - Installs `@tanstack/react-query` only when needed. - Adds or reuses a top-level `QueryClientProvider`. - Creates shared query keys and query/mutation wrappers. - Refactors network-backed reads and writes into TanStack Query. - Leaves imperative side effects outside Query when that is the safer model. ## License MIT -
SKILL.md 8.2 KB
--- name: lov-install-tanstack-query description: > Initialize or refactor a frontend project to use TanStack Query as the unified server-state layer. Use when the user asks to install TanStack Query, initialize query infrastructure, migrate ad hoc fetch/invoke/useEffect request state, standardize query keys, or make app network requests share one cache model. Also trigger when the user mentions "初始化 TanStack Query", "重构网络请求", "统一请求缓存", "install-tanstack-query", "TanStack Query refactor", or "useInvokeQuery". license: MIT compatibility: > React / TypeScript / JavaScript frontend projects, including Vite, Next.js, Tauri, Electron, and SPA apps. Requires the project's package manager. metadata: author: contributors version: "0.2.0" tags: tanstack-query react-query frontend refactor tauri network --- # TanStack Query 接入 · TanStack Query Setup Use this skill to add TanStack Query to a project or refactor existing request state into a shared query/mutation layer. ## When to Use - The user asks to install or initialize TanStack Query / React Query. - The project has repeated `useEffect + useState + fetch/invoke` request code. - The user wants all network-backed reads to share cache, refetch, invalidation, and loading/error behavior. - A Tauri app uses many `invoke()` reads that should be treated as server state. - The user mentions RTK Query but the project already uses, or prefers, TanStack Query. ## Workflow ### Step 1: Read Local Rules First Before changing files, inspect local instructions and project shape: ```bash pwd find .. -name AGENTS.md -print rg -n "@tanstack/react-query|react-query|@reduxjs/toolkit|createApi|useQuery|useMutation|fetch\\(|invoke\\(" package.json src app pages components 2>/dev/null ``` Honor project-specific constraints. If local instructions say not to run `build`, do not run it. Prefer `rg` and inspect existing patterns before adding new abstractions. ### Step 2: Classify Request Code Separate code into three buckets: | Bucket | Examples | TanStack Query? | |---|---|---| | Server state reads | list/get/search/version/status/catalog/settings loaded from network or Tauri backend | Yes, `useQuery` | | Server state writes | save/delete/toggle/install request, followed by cache changes | Yes, `useMutation` | | Imperative side effects | terminal I/O, file open, clipboard, app relaunch, installer progress events, streaming channels | Usually no | Do not force command-style effects into Query just to make the code look uniform. The goal is unified server state, not hiding every side effect. ### Step 3: Install Only If Needed Check `package.json` first. If TanStack Query is absent, detect package manager from lockfiles and install: ```bash pnpm add @tanstack/react-query npm install @tanstack/react-query yarn add @tanstack/react-query bun add @tanstack/react-query ``` Only add persistence or devtools when the project already uses them or the user explicitly asks: ```bash pnpm add @tanstack/react-query-persist-client @tanstack/query-sync-storage-persister pnpm add -D @tanstack/react-query-devtools ``` ### Step 4: Add Provider Add one top-level `QueryClientProvider` near the app root. Keep it consistent with the existing architecture. Recommended defaults: ```tsx import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: Infinity, refetchOnWindowFocus: false, retry: false, }, }, }); root.render( <QueryClientProvider client={queryClient}> <App /> </QueryClientProvider>, ); ``` Adjust defaults for product needs. Data that changes frequently should use a shorter `staleTime`, polling, streaming, or explicit invalidation. ### Step 5: Create Shared Query Infrastructure Prefer small local wrappers over scattering raw `useQuery` calls everywhere. For Tauri apps: ```ts import { invoke } from "@tauri-apps/api/core"; import { useMutation, useQuery, useQueryClient, type QueryKey, type UseQueryOptions, type UseMutationOptions, } from "@tanstack/react-query"; type InvokeQueryOptions<TQueryFnData, TData> = Omit< UseQueryOptions<TQueryFnData, Error, TData, QueryKey>, "queryKey" | "queryFn" >; export function useInvokeQuery<TQueryFnData, TData = TQueryFnData>( queryKey: QueryKey, command: string, args?: Record<string, unknown>, options?: InvokeQueryOptions<TQueryFnData, TData>, ) { return useQuery<TQueryFnData, Error, TData, QueryKey>({ queryKey, queryFn: () => invoke<TQueryFnData>(command, args), staleTime: Infinity, refetchOnMount: false, refetchOnWindowFocus: false, ...options, }); } type InvokeMutationOptions<T, V> = Omit<UseMutationOptions<T, Error, V>, "mutationFn">; export function useInvokeMutation<T, V = void>( command: string, invalidateKeys?: QueryKey[], options?: InvokeMutationOptions<T, V>, ) { const queryClient = useQueryClient(); return useMutation<T, Error, V>({ mutationFn: (variables) => invoke<T>(command, variables as Record<string, unknown>), ...options, onSuccess: (data, variables, context, mutation) => { options?.onSuccess?.(data, variables, context, mutation); invalidateKeys?.forEach((key) => { queryClient.invalidateQueries({ queryKey: key }); }); }, }); } ``` Add stable query keys: ```ts export const queryKeys = { projects: ["projects"] as const, settings: ["settings"] as const, }; ``` For REST apps, use the same structure but wrap the project's API client instead of Tauri `invoke()`. ### Step 6: Refactor Incrementally Start with duplicated and user-visible requests: 1. Replace manual read state: ```tsx const { data = [], isLoading, error, refetch } = useInvokeQuery<Item[]>( queryKeys.items, "list_items", ); ``` 2. Replace write requests: ```tsx const saveItem = useInvokeMutation<Item, { item: Item }>( "save_item", [queryKeys.items], ); ``` 3. Use `queryClient.setQueryData()` for optimistic toggles when the UX needs instant feedback. 4. Keep local UI state local. Dialog open state, form drafts, selected tabs, and filters usually do not belong in TanStack Query. 5. Do not break existing streaming subscriptions. If a stream already pushes data into `queryClient.setQueryData()`, keep that pattern. ### Step 7: Verification Run the lightest reliable checks allowed by the repo: ```bash pnpm exec tsc --noEmit --pretty false npm run typecheck yarn typecheck bun run typecheck ``` Do not run heavy builds or dev server commands if local instructions forbid them. For UI-heavy changes, suggest browser verification or screenshots after type checks pass. ## Final Response Checklist Report: - What query provider/wrappers/keys were added or reused. - Which request flows moved to TanStack Query. - Which imperative flows intentionally stayed command-driven. - Which checks were run and whether any warnings remain. ## Runtime context (shared) 运行前读取本 Skill 包的 `skill.yaml`,由宿主提供 `skill-runtime/v1` 上下文。字段解析顺序为:当前请求、项目上下文、个人 Preferences、品牌 Profile、通用默认值。 - 只使用 Manifest 声明的字段;Profile 保存公开品牌事实,Preferences 保存个人工作偏好。 - `required: true` 字段缺失时,按 Manifest 的问题配置向用户提出一个聚焦问题;用户明确同意后再保存回答。 - 报错提供可复制的 `context_id`、字段路径与来源,诊断内容避开秘密、完整私人路径和原始配置。 ## 通用反馈闭环 用户在 Skill 驱动任务中提出修改意见时,继续当前产物前必须执行: 1. 先判断意见是 `task-specific`(仅本次)还是 `reusable`(可跨任务复用)。 2. `task-specific` 只修改当前任务,不改 Skill。 3. `reusable` 先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。 4. 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。 5. `reusable` 修改会使此前的“确认”“继续”“发吧”失效;完成当前产物修改和回读后必须停下,等待用户下一步指示,不自动进入发布、提交或其他外部写入。 -
skill.yaml 859 B
schema: skill-manifest/v1 id: lov-install-tanstack-query version: "0.2.0" runtime: skill-runtime/v1 context: profile: fields: - path: identity.name required: false question: 如果本次输出需要品牌身份,请提供品牌名称。 - path: identity.logo required: false question: 如果需要使用品牌 Logo,请提供 Logo 地址或文件路径。 - path: brand.tone required: false question: 如果已有品牌语气或审美关键词,请提供它们。 preferences: namespace: lov_install_tanstack_query fields: - path: user.language required: false question: 希望使用哪种语言输出? - path: user.timezone required: false question: 需要使用哪个时区处理日期和时间? interaction: ask_missing: true max_questions: 1
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.