From web-server-state-react-query
React Query server state, hey-api OpenAPI codegen, type-safe data fetching
How this skill is triggered — by the user, by Claude, or both
Slash command
/web-server-state-react-query:web-server-state-react-queryThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Quick Guide:** Generate type-safe React Query hooks from OpenAPI specs using hey-api. Never write custom query hooks or manual type definitions -- use generated query options (`getFeaturesOptions()` pattern) and generated types. Configure the client once via environment variables. All timeouts/retries use named constants.
Quick Guide: Generate type-safe React Query hooks from OpenAPI specs using hey-api. Never write custom query hooks or manual type definitions -- use generated query options (
getFeaturesOptions()pattern) and generated types. Configure the client once via environment variables. All timeouts/retries use named constants.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use generated query options from hey-api -- NEVER write custom React Query hooks)
(You MUST regenerate client code when OpenAPI schema changes)
(You MUST use named constants for ALL timeout/retry values -- NO magic numbers)
(You MUST configure API client base URL via environment variables)
</critical_requirements>
Auto-detection: OpenAPI schema, hey-api, openapi-ts, generated React Query hooks, query options, getFeaturesOptions, useQuery, useMutation, QueryClient, QueryClientProvider, staleTime, gcTime, queryKey
When to use:
When NOT to use:
OpenAPI-first development ensures a single source of truth for your API contract. The hey-api code generator (@hey-api/openapi-ts) transforms your OpenAPI schema into fully typed client code, React Query hooks, and query options -- eliminating manual type definitions and reducing bugs.
Core Principles:
Configure @hey-api/openapi-ts to generate TypeScript client code and React Query hooks from your OpenAPI spec. Since v0.73.0, client packages are bundled -- no separate installation needed.
// openapi-ts.config.ts
import { defineConfig } from "@hey-api/openapi-ts";
export default defineConfig({
input: "./openapi.yaml",
output: "src/api-client",
plugins: [
"@hey-api/typescript",
"@hey-api/sdk",
"@tanstack/react-query",
// "@hey-api/client-fetch" -- optional, Fetch is the default client since v0.73
],
});
Key points: @hey-api/typescript generates types (renamed from @hey-api/types), @hey-api/sdk generates service functions (renamed from @hey-api/services). Fetch client is bundled by default since v0.73 -- only add @hey-api/client-fetch explicitly to customize its options. Run generation via npx openapi-ts or add as a build script.
See examples/core.md Pattern 1 for generated output structure and usage.
Configure the API client base URL and QueryClient defaults once in a provider component. Use environment variables for the base URL so it works across environments without code changes.
const FIVE_MINUTES_MS = 5 * 60 * 1000;
// In your provider component:
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: { staleTime: FIVE_MINUTES_MS, refetchOnWindowFocus: false },
},
}),
);
client.setConfig({ baseUrl: process.env.API_BASE_URL ?? "" });
Key points: hey-api's client.setConfig() merges with existing config (doesn't replace). Named constants for all time values. Set auth option or use interceptors for auth headers.
See examples/core.md Pattern 2 for full provider setup and auth configuration.
Use generated query options directly -- never write custom React Query hooks. Options are fully typed and include generated query keys.
import { useQuery } from "@tanstack/react-query";
import { getFeaturesOptions } from "./api-client/@tanstack/react-query.gen";
// Direct usage -- fully typed
const { data, isPending, error } = useQuery(getFeaturesOptions());
// With overrides -- spread and customize
const TEN_MINUTES_MS = 10 * 60 * 1000;
const { data } = useQuery({
...getFeaturesOptions(),
staleTime: TEN_MINUTES_MS,
enabled: someCondition,
});
Why good: Zero boilerplate, type-safe, consistent patterns, query keys auto-namespaced, easy to customize by spreading
See examples/core.md Pattern 3 for component examples and bad patterns to avoid.
React Query v5 removed onError/onSuccess/onSettled callbacks from useQuery. Use component-level isPending/error states, useEffect for error side effects, or global handlers via QueryCache/MutationCache.
// Global error handling (v5 pattern)
new QueryClient({
queryCache: new QueryCache({
onError: (error, query) => {
if (query.state.data !== undefined) {
showNotification(`Something went wrong: ${error.message}`);
}
},
}),
mutationCache: new MutationCache({
onError: (error) => {
showNotification("Operation failed. Please try again.");
},
}),
});
See examples/error-handling.md for component-level handling, retry with exponential backoff, and error boundaries.
Debounce search/filter queries to prevent excessive API calls on every keystroke.
const DEBOUNCE_DELAY_MS = 500;
const MIN_SEARCH_LENGTH = 0;
const debouncedTerm = useDebounce(searchTerm, DEBOUNCE_DELAY_MS);
const { data } = useQuery({
queryKey: ["search", debouncedTerm],
queryFn: () => searchAPI(debouncedTerm),
enabled: debouncedTerm.length > MIN_SEARCH_LENGTH,
});
Why good: Prevents excessive API calls, query key includes debounced term for proper cache management, enabled prevents empty queries
Detailed Resources:
<red_flags>
High Priority Issues:
FIVE_MINUTES_MS, MAX_RETRY_ATTEMPTS)onError/onSuccess callbacks on useQuery -- removed in React Query v5Medium Priority Issues:
retry: true in development with mocks -- should be false to fail fastGotchas & Edge Cases:
cacheTime was renamed to gcTime in v5 (garbage collection time)isLoading was renamed to isPending in v5keepPreviousData replaced with placeholderData: (prev) => prevuseInfiniteQuery now requires initialPageParam optionclient.setConfig() merges with existing config, doesn't replace itstaleTime/gcTime</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md
(You MUST use generated query options from hey-api -- NEVER write custom React Query hooks)
(You MUST regenerate client code when OpenAPI schema changes)
(You MUST use named constants for ALL timeout/retry values -- NO magic numbers)
(You MUST configure API client base URL via environment variables)
Failure to follow these rules will cause type drift, inconsistent patterns, and production bugs.
</critical_reminders>
npx claudepluginhub agents-inc/skills --plugin web-server-state-react-queryProvides TanStack Query v5 reference for React data fetching, caching, server state management using useQuery/useMutation hooks, QueryClient setup, optimistic updates, Next.js SSR/hydration, testing, TypeScript, and advanced patterns.
Guides TanStack Query v5 (React Query) for React server state management: data fetching, caching, mutations, v4 migrations, stale data, invalidation, and optimistic updates.
Expert TanStack Query guidance for React and Next.js apps covering asynchronous state management, data fetching, caching, mutations, optimistic updates, and SSR integration.