Claude Skill

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

LLM Mart · 0 points · 11 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download lovstudio-skills-skills_install-tanstack-query-0b16007.zip · 6 KB
Part of lovstudio/skills — 83 skills

Install

skills CLI npx skills add https://github.com/lovstudio/skills/tree/main/skills/install-tanstack-query
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lovstudio-skills@llmmart
Git 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

Version

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-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 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/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:

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:

  1. Replace manual read state:
const { data = [], isLoading, error, refetch } = useInvokeQuery<Item[]>(
  queryKeys.items,
  "list_items",
);
  1. Replace write requests:
const saveItem = useInvokeMutation<Item, { item: Item }>(
  "save_item",
  [queryKeys.items],
);
  1. Use queryClient.setQueryData() for optimistic toggles when the UX needs instant feedback.

  2. Keep local UI state local. Dialog open state, form drafts, selected tabs, and filters usually do not belong in TanStack Query.

  3. 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 驱动任务中提出修改意见时,继续当前产物前必须执行:

  1. 先判断意见是 task-specific(仅本次)还是 reusable(可跨任务复用)。
  2. task-specific 只修改当前任务,不改 Skill。
  3. reusable 先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。
  4. 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。
  5. 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
    
    ![Version](https://img.shields.io/badge/version-0.2.0-CC785C)
    
    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.

No comments yet.

Reviews (0)

No reviews yet.

Related