tanstack
Type-safe React with TanStack Query (fetching, caching, mutations), Router (file-based routing, search params, loaders), and Start (SSR, server functions). Use for react-query, server state, typed search params, route loaders, or SSR. Skill: tanstack Owner: tenequm Summary: Type-safe React with TanStack Query (fetching, caching, mutations), Router (file-based routing, search params, loaders), and Start (SSR, server functions). Use for react-query, server state, typed search params, route loaders, or SSR. Tags: latest:0.4.5 Version history: v0.4.5 | 2026-09-09T10:12:50.554Z | user Updated tanstack from 0.4.4 to 0.4.5. Changes: - modified CHANGELOG.
Rank
62
Safety
84
Downloads
2.0k
Updated
Oct 9, 2026
Version
0.4.5
Source
CLAWHUB
About
What it does, and when to use it.
Capability contract not published. No trust telemetry is available yet. 2K downloads reported by the source. Last updated 10/9/2026.
Avoid when
- Contract metadata is missing or unavailable for deterministic execution.
Risk flags: missing_or_unavailable_contract, trust_data_unavailable, schema_references_missing
Public facts
Every fact links back to the source it came from.
- Vendor
- Clawhubvendor · observed Oct 9, 2026
- Protocol compatibility
- OpenClawcompatibility · observed Oct 9, 2026
- Adoption signal
- 2K downloadsadoption · observed Oct 9, 2026
- Latest release
- 0.4.5release · observed Sep 9, 2026
- Handshake status
- UNKNOWNsecurity
Install and run
Setup complexity: low.
clawhub skill install s17bp3v1hm1dnkzey0c9tfh02183j0y5:tanstack- Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.
- Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.
Contract: missing
curl -s "https://www.xpersona.co/api/v1/agents/clawhub-tenequm-tanstack/snapshot"
Documentation
CLAWHUB
150,937 characters of source documentation, loaded on request.
Extracted files
5 files captured from the source.
SKILL.md
--- name: tanstack description: Type-safe React with TanStack Query (fetching, caching, mutations), Router (file-based routing, search params, loaders), and Start (SSR, server functions). Use for react-query, server state, typed search params, route loaders, or SSR. metadata: version: "0.4.5" categories: "development" topics: "tanstack, react, routing, data-fetching, ssr" upstream: "@tanstack/[email protected], @tanstack/[email protected], @tanstack/[email protected], @tanstack/[email protected], @tanstack/[email protected]" openclaw: homepage: https://github.com/tenequm/skills/tree/main/skills/tanstack emoji: "⚛️" --- # TanStack (Query + Router + Start) Type-safe libraries for React applications. **Query** manages server state (fetching, caching, mutations). **Router** provides file-based routing with validated search params and data loaders. **Start** extends Router with SSR, server functions, and middleware for full-stack apps. ## When to Use **Query** - data fetching, caching, mutations, optimistic updates, infinite scroll, streaming AI/SSE responses, tRPC v11 integration **Router** - file-based routing, type-safe navigation, validated search params, route loaders, code splitting, preloading **Start** - SSR/SSG, server functions (type-safe RPCs), middleware, API routes, deployment to Cloudflare/Vercel/Node **Decision tree:** - Client-only SPA with API calls -> Router + Query - Full-stack with SSR/server functions -> Start + Query (Start includes Router) ## TanStack Query v5 ### Setup ```tsx import { QueryClient, QueryClientProvider } from '@tanstack/react-query' const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 5, // 5 minutes }, }, }) function App() { return ( <QueryClientProvider client={queryClient}> <YourApp /> </QueryClientProvider> ) } ``` ### Queries ```tsx import { useQuery, queryOptions } from '@tanstack/react-query' // Reusable query definition (recommended pattern) const todosQueryOptions = queryOptions({ queryKey: ['todos'], queryFn: async () => { const res = await fetch('/api/todos') if (!res.ok) throw new Error('Failed to fetch') return res.json() as Promise<Todo[]> }, }) // In component - full type inference from queryOptions function TodoList() { const { data, isLoading, error } = useQuery(todosQueryOptions) if (isLoading) return <Spinner /> if (error) return <div>Error: {error.message}</div> return <ul>{data.map(t => <li key={t.id}>{t.title}</li>)}</ul> } ``` ### Mutations ```tsx import { useMutation, useQueryClient } from '@tanstack/react-query' function CreateTodo() { const queryClient = useQueryClient() const mutation = useMutation({ mutationFn: (newTodo: { title: string }) => fetch('/api/todos', { method: 'POST', body: JSON.stringify(newTodo) }).then(r => r.json()), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['todos'] }) },
_meta.json
{
"ownerId": "kn76gpsgjw5chv0xvzbzcb8cxn81x46r",
"slug": "tanstack",
"version": "0.4.5",
"publishedAt": 1788948770554
}references/code-splitting.md
# Code Splitting and Preloading
Optimize TanStack Router applications with code splitting, lazy loading, and preloading for faster initial loads and seamless navigation.
Official docs:
- https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting
- https://tanstack.com/router/latest/docs/framework/react/guide/automatic-code-splitting
- https://tanstack.com/router/latest/docs/framework/react/guide/preloading
- https://tanstack.com/router/latest/docs/framework/react/guide/render-optimizations
## Critical vs Non-Critical Route Configuration
TanStack Router separates route configuration into two categories.
**Critical (always in the main bundle)** - required to match the route and start data loading:
- Path parsing and serialization
- Search parameter validation
- Loaders (`loader`) and before load hooks (`beforeLoad`)
- Route context, static data, styles, scripts, links
**Non-Critical (can be lazy-loaded)** - not required to match the route:
- `component` - the route component
- `errorComponent` - rendered when a loader or component throws
- `pendingComponent` - rendered while the route is loading
- `notFoundComponent` - rendered when a not-found error is thrown
**Why the loader stays in the main bundle:** The loader is already an async boundary, so splitting it adds a second async hop (fetch the chunk, then execute the loader). Loaders are typically smaller than components and are critical for preloading on hover/touch - they must be available without additional async overhead.
## Automatic Code Splitting
Enable it in the bundler plugin and TanStack Router handles everything. Only works with file-based routing and a supported bundler plugin (`@tanstack/router-plugin`), not with the standalone CLI or code-based routing.
```ts
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
export default defineConfig({
plugins: [
tanstackRouter({ autoCodeSplitting: true }),
react(), // Must come AFTER the TanStack Router plugin
],
})
```
The plugin transforms each route file at build time into a **reference file** (original file rewritten with lazy-loading wrappers) and **virtual files** (minimal files containing only the code for a single property like `component`).
### Default Split Groupings
Three separate lazy-loaded chunks are created per route by default:
```ts
[['component'], ['errorComponent'], ['notFoundComponent']]
```
The `pendingComponent` and `loader` remain in the main bundle.
### Customizing Split Groupings
**Global default behavior** - bundle all UI components into one chunk:
```ts
// vite.config.ts
tanstackRouter({
autoCodeSplitting: true,
codeSplittingOptions: {
defaultBehavior: [
['component', 'pendingComponent', 'errorComponent', 'notFoundComponent'],
],
},
})
```
**Programmatic per-route-id control** with `splitBehavior`:
```ts
tanstackRouter({
autoCodeSplitting: trreferences/data-loading.md
# Data Loading
TanStack Router provides a built-in data loading system with route loaders, SWR caching, and deep integration points for external libraries like TanStack Query.
Official docs: https://tanstack.com/router/latest/docs/framework/react/guide/data-loading
## Route Loaders
The `loader` function is the primary mechanism for loading data. It runs before the route component renders and receives a single object parameter.
### Loader Function Signature
```tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts')({
loader: async ({
params, // Route path params (e.g., { postId: '1' })
deps, // Object from loaderDeps, or {} if not defined
context, // Merged route context (parent + beforeLoad)
abortController, // Cancelled on unload or outdated invocation
preload, // true when preloading instead of loading
cause, // 'enter' | 'stay' | 'preload'
location, // Current location object
route, // The route object itself
parentMatchPromise, // Promise for parent match (undefined for root)
}) => {
return await fetchPosts()
},
})
```
### Basic Examples
```tsx
// Simple data fetch
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
})
// Using path params
export const Route = createFileRoute('/posts/$postId')({
loader: ({ params: { postId } }) => fetchPost(postId),
})
// Using the abort signal
export const Route = createFileRoute('/posts')({
loader: ({ abortController }) =>
fetch('/api/posts', { signal: abortController.signal }).then((r) => r.json()),
})
// Conditional logic based on preload
export const Route = createFileRoute('/posts')({
loader: async ({ preload }) =>
fetchPosts({ maxAge: preload ? 10_000 : 0 }),
})
```
## Consuming Loader Data
### useLoaderData and getRouteApi
```tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
component: PostsComponent,
})
function PostsComponent() {
// Option 1: directly from Route object
const posts = Route.useLoaderData()
return <ul>{posts.map((p) => <li key={p.id}>{p.title}</li>)}</ul>
}
// Option 2: getRouteApi - avoids circular imports in deep components
import { getRouteApi } from '@tanstack/react-router'
const routeApi = getRouteApi('/posts')
function PostsList() {
const posts = routeApi.useLoaderData()
return <ul>{posts.map((p) => <li key={p.id}>{p.title}</li>)}</ul>
}
```
### useRouteContext
Access route context (including data injected via `beforeLoad`):
```tsx
function PostsComponent() {
const { user, permissions } = Route.useRouteContext()
}
```
## Loader Dependencies (loaderDeps)
`loaderDeps` extracts dependencies from search params to serve as cache keys. When deps change between navigations, the loader re-runs regardless of `staleTime`.
Search params are deliberately not available directly in `loader` - this forcreferences/infinite-queries.md
# Infinite Queries
Infinite queries are used for implementing "load more" and infinite scroll patterns. They allow you to fetch paginated data progressively.
## Basic Infinite Query
```tsx
import { useInfiniteQuery } from '@tanstack/react-query';
function Posts() {
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
isLoading,
} = useInfiniteQuery({
queryKey: ['posts'],
queryFn: async ({ pageParam = 0 }) => {
const res = await fetch(`/api/posts?cursor=${pageParam}`);
return res.json();
},
initialPageParam: 0,
getNextPageParam: (lastPage, allPages) => {
// Return undefined if no more pages
return lastPage.nextCursor ?? undefined;
},
});
if (isLoading) return <div>Loading...</div>;
return (
<>
{data.pages.map((page, i) => (
<div key={i}>
{page.posts.map((post) => (
<div key={post.id}>{post.title}</div>
))}
</div>
))}
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetchingNextPage}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</>
);
}
```
## Data Structure
The `data` object has a specific structure:
```tsx
{
pages: [
{ posts: [...], nextCursor: 1 }, // Page 1
{ posts: [...], nextCursor: 2 }, // Page 2
{ posts: [...], nextCursor: 3 }, // Page 3
],
pageParams: [0, 1, 2] // The pageParam values used
}
```
## Page Parameters
### initialPageParam
Required parameter that specifies the initial page parameter:
```tsx
useInfiniteQuery({
queryKey: ['posts'],
queryFn: ({ pageParam }) => fetchPosts(pageParam),
initialPageParam: 0, // or 1, or { cursor: null }, etc.
getNextPageParam: (lastPage) => lastPage.nextCursor,
});
```
### getNextPageParam
Function that receives the last page and all pages, and returns the next page parameter:
```tsx
// Cursor-based pagination
getNextPageParam: (lastPage, allPages) => {
return lastPage.nextCursor ?? undefined;
}
// Offset-based pagination
getNextPageParam: (lastPage, allPages) => {
if (lastPage.length === 0) return undefined;
return allPages.length * 10; // Assuming 10 items per page
}
// Page number pagination
getNextPageParam: (lastPage, allPages) => {
const totalPages = lastPage.totalPages;
const nextPage = allPages.length + 1;
return nextPage <= totalPages ? nextPage : undefined;
}
// Access to all pages
getNextPageParam: (lastPage, allPages) => {
const totalFetched = allPages.reduce((acc, page) => acc + page.data.length, 0);
return totalFetched < lastPage.total ? lastPage.nextCursor : undefined;
}
```
### getPreviousPageParam
For bidirectional infinite scrolling:
```tsx
useInfiniteQuery({
queryKey: ['posts'],
queryFn: ({ pageParam }) => fetchPosts(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextCurAionUi
Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!
activepieces
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
cherry-studio
AI productivity studio with smart chat, autonomous agents, and 300+ assistants.
CopilotKit
The Frontend for Agents & Generative UI. React + Angular
Machine-readable data
The same record, as JSON, for agents and crawlers.
{
"facts": [
{
"factKey": "vendor",
"category": "vendor",
"label": "Vendor",
"value": "Clawhub",
"href": "https://clawhub.ai/tenequm/skills/tanstack",
"sourceUrl": "https://clawhub.ai/tenequm/skills/tanstack",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-09T20:54:09.118Z",
"isPublic": true
},
{
"factKey": "protocols",
"category": "compatibility",
"label": "Protocol compatibility",
"value": "OpenClaw",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-tenequm-tanstack/contract",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-tenequm-tanstack/contract",
"sourceType": "contract",
"confidence": "medium",
"observedAt": "2026-10-09T20:54:09.118Z",
"isPublic": true
},
{
"factKey": "traction",
"category": "adoption",
"label": "Adoption signal",
"value": "2K downloads",
"href": "https://clawhub.ai/tenequm/tanstack",
"sourceUrl": "https://clawhub.ai/tenequm/tanstack",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-09T20:54:09.118Z",
"isPublic": true
},
{
"factKey": "latest_release",
"category": "release",
"label": "Latest release",
"value": "0.4.5",
"href": "https://clawhub.ai/tenequm/tanstack",
"sourceUrl": "https://clawhub.ai/tenequm/tanstack",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-09-09T10:12:50.554Z",
"isPublic": true
},
{
"factKey": "handshake_status",
"category": "security",
"label": "Handshake status",
"value": "UNKNOWN",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-tenequm-tanstack/trust",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-tenequm-tanstack/trust",
"sourceType": "trust",
"confidence": "medium",
"observedAt": null,
"isPublic": true
}
],
"events": [
{
"eventType": "release",
"title": "Release 0.4.5",
"description": "Updated tanstack from 0.4.4 to 0.4.5. Changes: - modified `CHANGELOG.md` - modified `SKILL.md`",
"href": "https://clawhub.ai/tenequm/tanstack",
"sourceUrl": "https://clawhub.ai/tenequm/tanstack",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-09-09T10:12:50.554Z",
"isPublic": true
}
]
}Record generated Oct 9, 2026.
