{"id":"0a0c8a1d-5169-4a08-92d4-04dacb299ca5","shortId":"SkKEa2","kind":"skill","title":"tanstack","tagline":"Build type-safe React apps with TanStack Query (data fetching, caching, mutations), Router (file-based routing, search params, loaders), and Start (SSR, server functions, middleware). Use when working with react-query, data fetching, server state, routing, search params, loaders,","description":"# TanStack (Query + Router + Start)\n\nType-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.\n\n## When to Use\n\n**Query** - data fetching, caching, mutations, optimistic updates, infinite scroll, streaming AI/SSE responses, tRPC v11 integration\n**Router** - file-based routing, type-safe navigation, validated search params, route loaders, code splitting, preloading\n**Start** - SSR/SSG, server functions (type-safe RPCs), middleware, API routes, deployment to Cloudflare/Vercel/Node\n\n**Decision tree:**\n- Client-only SPA with API calls -> Router + Query\n- Full-stack with SSR/server functions -> Start + Query (Start includes Router)\n\n## TanStack Query v5\n\n### Setup\n\n```tsx\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\n\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      staleTime: 1000 * 60 * 5, // 5 minutes\n    },\n  },\n})\n\nfunction App() {\n  return (\n    <QueryClientProvider client={queryClient}>\n      <YourApp />\n    </QueryClientProvider>\n  )\n}\n```\n\n### Queries\n\n```tsx\nimport { useQuery, queryOptions } from '@tanstack/react-query'\n\n// Reusable query definition (recommended pattern)\nconst todosQueryOptions = queryOptions({\n  queryKey: ['todos'],\n  queryFn: async () => {\n    const res = await fetch('/api/todos')\n    if (!res.ok) throw new Error('Failed to fetch')\n    return res.json() as Promise<Todo[]>\n  },\n})\n\n// In component - full type inference from queryOptions\nfunction TodoList() {\n  const { data, isLoading, error } = useQuery(todosQueryOptions)\n  if (isLoading) return <Spinner />\n  if (error) return <div>Error: {error.message}</div>\n  return <ul>{data.map(t => <li key={t.id}>{t.title}</li>)}</ul>\n}\n```\n\n### Mutations\n\n```tsx\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\nfunction CreateTodo() {\n  const queryClient = useQueryClient()\n  const mutation = useMutation({\n    mutationFn: (newTodo: { title: string }) =>\n      fetch('/api/todos', { method: 'POST', body: JSON.stringify(newTodo) }).then(r => r.json()),\n    onSuccess: () => {\n      queryClient.invalidateQueries({ queryKey: ['todos'] })\n    },\n  })\n\n  return (\n    <button onClick={() => mutation.mutate({ title: 'New' })}>\n      {mutation.isPending ? 'Creating...' : 'Create'}\n    </button>\n  )\n}\n```\n\n### Key Patterns\n\n**Query keys** - hierarchical arrays for cache management:\n```tsx\n['todos']                          // all todos\n['todos', 'list', { page, sort }]  // filtered list\n['todo', todoId]                   // single item\n```\n\n**Dependent queries** - chain with `enabled`:\n```tsx\nconst { data: user } = useQuery({ queryKey: ['user', id], queryFn: () => fetchUser(id) })\nconst { data: projects } = useQuery({\n  queryKey: ['projects', user?.id],\n  queryFn: () => fetchProjects(user!.id),\n  enabled: !!user?.id,\n})\n```\n\n**Important defaults**: staleTime: 0, gcTime: 5min, retry: 3, refetchOnWindowFocus: true\n\n**Suspense** - use `useSuspenseQuery` with `<Suspense>` boundaries\n\n**Streamed queries** (experimental) - for AI chat/SSE:\n```tsx\nimport { experimental_streamedQuery as streamedQuery } from '@tanstack/react-query'\n\nconst { data: chunks } = useQuery(queryOptions({\n  queryKey: ['chat', sessionId],\n  queryFn: streamedQuery({ streamFn: () => fetchChatStream(sessionId), refetchMode: 'reset' }),\n}))\n```\n\n### DevTools\n\n```bash\npnpm add @tanstack/react-query-devtools\n```\n```tsx\nimport { ReactQueryDevtools } from '@tanstack/react-query-devtools'\n// Add inside QueryClientProvider\n<ReactQueryDevtools initialIsOpen={false} />\n```\n\n### Query Deep Dives\n\n- `query-guide.md` - Complete Query reference with all patterns\n- `infinite-queries.md` - useInfiniteQuery, pagination, virtual scroll\n- `optimistic-updates.md` - Optimistic UI, rollback, undo\n- `query-performance.md` - staleTime tuning, deduplication, prefetching\n- `query-invalidation.md` - Cache invalidation strategies, filters, predicates\n- `query-typescript.md` - Type inference, generics, custom hooks\n\n---\n\n## TanStack Router v1\n\n### Setup (Vite)\n\n```bash\npnpm add @tanstack/react-router @tanstack/router-plugin\n```\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\n\nexport default defineConfig({\n  plugins: [\n    tanstackRouter({ autoCodeSplitting: true }),\n    react(),\n  ],\n})\n```\n\n```tsx\n// src/router.ts\nimport { createRouter } from '@tanstack/react-router'\nimport { routeTree } from './routeTree.gen'\n\nexport const router = createRouter({ routeTree, defaultPreload: 'intent' })\n\ndeclare module '@tanstack/react-router' {\n  interface Register { router: typeof router }\n}\n```\n\n### File-Based Routing\n\nFiles in `src/routes/` auto-generate route config:\n\n| Convention | Purpose | Example |\n|---|---|---|\n| `__root.tsx` | Root route (always rendered) | `src/routes/__root.tsx` |\n| `index.tsx` | Index route | `src/routes/index.tsx` -> `/` |\n| `$param` | Dynamic segment | `posts.$postId.tsx` -> `/posts/:id` |\n| `_prefix` | Pathless layout | `_layout.tsx` wraps children |\n| `(folder)` | Route group (no URL) | `(auth)/login.tsx` -> `/login` |\n\n### Type-Safe Navigation\n\n```tsx\n<Link to=\"/posts/$postId\" params={{ postId: '123' }}>View Post</Link>\n\n// Active styling\n<Link to=\"/posts\" activeProps={{ className: 'font-bold' }}>Posts</Link>\n\n// Imperative\nconst navigate = useNavigate({ from: '/posts' })\nnavigate({ to: '/posts/$postId', params: { postId: post.id } })\n```\n\nAlways provide `from` on Link and hooks - narrows types and improves TS performance.\n\n### Search Params\n\n```tsx\nimport { zodValidator, fallback } from '@tanstack/zod-adapter'\nimport { z } from 'zod'\n\nconst searchSchema = z.object({\n  page: fallback(z.number(), 1).default(1),\n  sort: fallback(z.enum(['newest', 'oldest']), 'newest').default('newest'),\n})\n\nexport const Route = createFileRoute('/products')({\n  validateSearch: zodValidator(searchSchema),\n  component: () => {\n    const { page, sort } = Route.useSearch()\n    // Writing\n    return <Link from={Route.fullPath} search={prev => ({ ...prev, page: prev.page + 1 })}>Next</Link>\n  },\n})\n```\n\nUse `fallback(...).default(...)` from the Zod adapter. Plain `.catch()` causes type loss.\n\n### Data Loading\n\n```tsx\nexport const Route = createFileRoute('/posts')({\n  // loaderDeps: only extract what loader needs (not full search)\n  loaderDeps: ({ search: { page } }) => ({ page }),\n  loader: ({ deps: { page } }) => fetchPosts({ page }),\n  pendingComponent: () => <Spinner />,\n  component: () => {\n    const posts = Route.useLoaderData()\n    return <PostList posts={posts} />\n  },\n})\n```\n\n### Route Context (Dependency Injection)\n\n```tsx\n// __root.tsx\ninterface RouterContext { queryClient: QueryClient }\nexport const Route = createRootRouteWithContext<RouterContext>()({ component: Root })\n\n// router.ts\nconst router = createRouter({ routeTree, context: { queryClient } })\n\n// Child route - queryClient available in loader\nexport const Route = createFileRoute('/posts')({\n  loader: ({ context: { queryClient } }) =>\n    queryClient.ensureQueryData(postsQueryOptions()),\n})\n```\n\n### Router Deep Dives\n\n- `router-guide.md` - Complete Router reference with all patterns\n- `search-params.md` - Custom serialization, Standard Schema, sharing params\n- `data-loading.md` - Deferred loading, streaming SSR, shouldReload\n- `routing-patterns.md` - Virtual routes, route masking, navigation blocking\n- `code-splitting.md` - Automatic/manual splitting strategies\n- `router-ssr.md` - SSR setup, streaming, hydration\n\n---\n\n## TanStack Start (RC)\n\nFull-stack framework extending Router with SSR, server functions, middleware. API stable, feature-complete. No RSC yet.\n\n### Setup\n\n```bash\npnpm create @tanstack/start@latest\n```\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport { tanstackStart } from '@tanstack/react-start/plugin/vite'\nimport viteReact from '@vitejs/plugin-react'\n\nexport default defineConfig({\n  plugins: [\n    tanstackStart(),\n    viteReact(), // MUST come after tanstackStart()\n  ],\n})\n```\n\n### Server Functions\n\nType-safe RPCs. Server code extracted from client bundles at build time.\n\n```tsx\nimport { createServerFn } from '@tanstack/react-start'\nimport { z } from 'zod'\n\n// GET - no input\nexport const getUsers = createServerFn({ method: 'GET' })\n  .handler(async () => db.users.findMany())\n\n// POST - validated input\nexport const createUser = createServerFn({ method: 'POST' })\n  .inputValidator(z.object({ name: z.string(), email: z.string().email() }))\n  .handler(async ({ data }) => db.users.create(data))\n\n// Call from loader\nexport const Route = createFileRoute('/users')({\n  loader: () => getUsers(),\n  component: () => {\n    const users = Route.useLoaderData()\n    return <UserList users={users} />\n  },\n})\n```\n\n**Critical**: Loaders are isomorphic (run on server AND client). Never put secrets in loaders - use `createServerFn()` instead.\n\n### Middleware\n\n```tsx\nimport { createMiddleware } from '@tanstack/react-start'\n\nconst authMiddleware = createMiddleware({ type: 'function' })\n  .server(async ({ next }) => {\n    const user = await getCurrentUser()\n    if (!user) throw redirect({ to: '/login' })\n    return next({ context: { user } })\n  })\n\nconst getProfile = createServerFn()\n  .middleware([authMiddleware])\n  .handler(async ({ context }) => context.user) // typed\n```\n\nGlobal middleware via `src/start.ts`:\n```tsx\nexport const startInstance = createStart(() => ({\n  requestMiddleware: [logger],    // all requests\n  functionMiddleware: [auth],     // all server functions\n}))\n```\n\n### SSR Modes\n\n| Mode | Use Case |\n|------|----------|\n| `true` (default) | SEO, performance |\n| `false` | Browser-only features |\n| `'data-only'` | Dashboards (data on server, render on client) |\n\nSPA mode: `tanstackStart({ spa: { enabled: true } })` in vite.config.ts\n\n### Deployment\n\n- **Cloudflare Workers**: `@cloudflare/vite-plugin` (official partner)\n- **Netlify**: `@netlify/vite-plugin-tanstack-start`\n- **Node/Vercel/Bun/Docker**: via Nitro\n- **Static**: `tanstackStart({ prerender: { enabled: true, crawlLinks: true } })`\n\n### Start Deep Dives\n\n- `start-guide.md` - Complete Start reference with all patterns\n- `server-functions.md` - Streaming, FormData, progressive enhancement\n- `middleware.md` - sendContext, custom fetch, global config\n- `ssr-modes.md` - Selective SSR, shellComponent, fallback rendering\n- `server-routes.md` - Dynamic params, wildcards, pathless layouts\n\n---\n\n## Best Practices\n\n1. **Use `queryOptions()` factory** for reusable, type-safe query definitions\n2. **Structure query keys hierarchically** - `['entity', 'action', { filters }]`\n3. **Set staleTime per data type** - static: `Infinity`, dynamic: `0`, moderate: `5min`\n4. **Always validate search params** with Zod via `zodValidator` + `fallback().default()`\n5. **Provide `from` on navigation** - narrows types, catches route mismatches\n6. **Use route context for DI** - pass QueryClient, auth via `createRootRouteWithContext`\n7. **Set `defaultPreload: 'intent'`** globally for perceived performance\n8. **Never put secrets in loaders** - use `createServerFn()` for server-only code\n9. **Compose middleware hierarchically** - global -> route -> function\n10. **Use `head()` on every content route** for SEO (title, description, OG tags)\n\n## Resources\n\n- **Query Docs**: https://tanstack.com/query/latest/docs/framework/react/overview\n- **Router Docs**: https://tanstack.com/router/latest/docs/framework/react/overview\n- **Start Docs**: https://tanstack.com/start/latest/docs/framework/react/overview\n- **GitHub**: https://github.com/TanStack/query | https://github.com/TanStack/router\n- **Discord**: https://discord.gg/tanstack","tags":["tanstack","skills","tenequm","agent-skills","ai-agents","claude-code","claude-skills","clawhub","erc-8004","mpp","openclaw","solana"],"capabilities":["skill","source-tenequm","skill-tanstack","topic-agent-skills","topic-ai-agents","topic-claude-code","topic-claude-skills","topic-clawhub","topic-erc-8004","topic-mpp","topic-openclaw","topic-skills","topic-solana","topic-x402"],"categories":["skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/tenequm/skills/tanstack","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add tenequm/skills","source_repo":"https://github.com/tenequm/skills","install_from":"skills.sh"}},"qualityScore":"0.461","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 23 github stars · SKILL.md body (11,852 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T01:01:41.482Z","embedding":null,"createdAt":"2026-04-18T23:05:30.415Z","updatedAt":"2026-04-22T01:01:41.482Z","lastSeenAt":"2026-04-22T01:01:41.482Z","tsv":"'/api/todos':211,275 '/login':550,948 '/login.tsx':549 '/posts':535,558,569,581,584,675,736 '/products':635 '/query/latest/docs/framework/react/overview':1175 '/router/latest/docs/framework/react/overview':1180 '/routetree.gen':489 '/start/latest/docs/framework/react/overview':1185 '/tanstack':1196 '/tanstack/query':1189 '/tanstack/router':1192 '/users':897 '0':354,1094 '1':620,622,654,1066 '10':1157 '1000':177 '123':562 '2':1077 '3':358,1085 '4':1097 '5':179,180,1108 '5min':356,1096 '6':1118 '60':178 '7':1129 '8':1137 '9':1150 'action':1083 'activ':565 'activeprop':570 'adapt':662 'add':398,405,455 'ai':370 'ai/sse':102 'alway':523,589,1098 'api':133,145,795 'app':7,88,183 'applic':54 'array':302 'async':206,867,886,937,959 'auth':548,977,1126 'authmiddlewar':932,957 'auto':513 'auto-gener':512 'autocodesplit':477 'automatic/manual':773 'avail':729 'await':209,941 'base':18,66,110,507 'bash':396,453,804 'best':1064 'block':771 'bodi':278 'bold':574 'boundari':365 'browser':992 'browser-on':991 'build':2,846 'bundl':844 'button':289 'cach':13,60,95,304,437 'call':146,890 'case':985 'catch':664,1115 'caus':665 'chain':322 'chat':386 'chat/sse':371 'child':726 'children':542 'chunk':382 'classnam':571 'client':141,186,843,916,1004 'client-on':140 'cloudflar':1014 'cloudflare/vercel/node':137 'cloudflare/vite-plugin':1016 'code':121,840,1149 'code-splitting.md':772 'come':830 'complet':415,746,799,1035 'compon':226,639,695,717,900 'compos':1151 'config':516,1051 'const':170,200,207,234,264,267,326,336,380,491,577,614,632,640,672,696,714,720,733,861,873,894,901,931,939,953,969 'content':1162 'context':704,724,738,951,960,1121 'context.user':961 'convent':517 'crawllink':1029 'creat':295,296,806 'createfilerout':634,674,735,896 'createmiddlewar':928,933 'createrootroutewithcontext':716,1128 'createrout':483,493,722 'createserverfn':850,863,875,923,955,1144 'createstart':971 'createtodo':263 'createus':874 'critic':908 'custom':446,753,1048 'dashboard':998 'data':11,36,73,93,235,327,337,381,668,887,889,996,999,1089 'data-loading.md':759 'data-on':995 'data.map':249 'db.users.create':888 'db.users.findmany':868 'decis':138 'declar':497 'dedupl':434 'deep':412,743,1032 'default':352,473,621,629,658,824,987,1107 'defaultopt':174 'defaultpreload':495,1131 'defer':760 'defineconfig':461,474,812,825 'definit':197,1076 'dep':690 'depend':320,705 'deploy':135,1013 'descript':1167 'devtool':395 'di':1123 'discord':1193 'discord.gg':1195 'discord.gg/tanstack':1194 'dive':413,744,1033 'doc':1172,1177,1182 'dynam':531,1059,1093 'email':882,884 'enabl':324,348,1009,1027 'enhanc':1045 'entiti':1082 'error':216,237,244,246 'error.message':247 'everi':1161 'exampl':519 'experiment':368,374 'export':472,490,631,671,713,732,823,860,872,893,968 'extend':76,788 'extract':678,841 'factori':1069 'fail':217 'fallback':607,618,624,657,1056,1106 'fals':410,990 'featur':798,994 'feature-complet':797 'fetch':12,37,59,94,210,219,274,1049 'fetchchatstream':391 'fetchpost':692 'fetchproject':345 'fetchus':334 'file':17,65,109,506,509 'file-bas':16,64,108,505 'filter':314,440,1084 'folder':543 'font':573 'font-bold':572 'formdata':1043 'framework':787 'full':86,150,227,683,785 'full-stack':85,149,784 'function':27,81,127,154,182,232,262,793,834,935,980,1156 'functionmiddlewar':976 'gctime':355 'generat':514 'generic':445 'get':857,865 'getcurrentus':942 'getprofil':954 'getus':862,899 'github':1186 'github.com':1188,1191 'github.com/tanstack/query':1187 'github.com/tanstack/router':1190 'global':963,1050,1133,1154 'group':545 'handler':866,885,958 'head':1159 'hierarch':301,1081,1153 'hook':447,595 'hydrat':780 'id':332,335,343,347,350,536 'imper':576 'import':165,190,257,351,373,401,460,464,468,482,486,605,610,811,815,819,849,853,927 'improv':599 'includ':158 'index':527 'index.tsx':526 'infer':229,444 'infin':1092 'infinit':99 'infinite-queries.md':421 'initialisopen':409 'inject':706 'input':859,871 'inputvalid':878 'insid':406 'instead':924 'integr':106 'intent':496,1132 'interfac':500,709 'invalid':438 'isload':236,241 'isomorph':911 'item':319 'json.stringify':279 'key':252,297,300,1080 'latest':808 'layout':539,1063 'layout.tsx':540 'li':251 'librari':51 'link':556,567,593,646 'list':311,315 'load':669,761 'loader':22,43,74,120,680,689,731,737,892,898,909,921,1142 'loaderdep':676,685 'logger':973 'loss':667 'manag':56,305 'mask':769 'method':276,864,876 'middlewar':28,83,132,794,925,956,964,1152 'middleware.md':1046 'minut':181 'mismatch':1117 'mode':982,983,1006 'moder':1095 'modul':498 'must':829 'mutat':14,61,96,255,268 'mutation.ispending':294 'mutation.mutate':291 'mutationfn':270 'name':880 'narrow':596,1113 'navig':115,554,578,582,770,1112 'need':681 'netlifi':1019 'netlify/vite-plugin-tanstack-start':1020 'never':917,1138 'new':172,215,293 'newest':626,628,630 'newtodo':271,280 'next':655,938,950 'nitro':1023 'node/vercel/bun/docker':1021 'offici':1017 'og':1168 'oldest':627 'onclick':290 'onsuccess':284 'optimist':97,427 'optimistic-updates.md':426 'page':312,617,641,652,687,688,691,693 'pagin':423 'param':21,42,71,118,530,560,586,603,758,1060,1101 'partner':1018 'pass':1124 'pathless':538,1062 'pattern':199,298,420,751,1040 'pendingcompon':694 'per':1088 'perceiv':1135 'perform':601,989,1136 'plain':663 'plugin':475,826 'pnpm':397,454,805 'post':277,533,564,575,697,701,702,869,877 'post.id':588 'postid':559,561,585,587 'postid.tsx':534 'postlist':700 'postsqueryopt':741 'practic':1065 'predic':441 'prefetch':435 'prefix':537 'preload':123 'prerend':1026 'prev':650,651 'prev.page':653 'progress':1044 'project':338,341 'promis':223 'provid':63,590,1109 'purpos':518 'put':918,1139 'queri':10,35,45,55,92,148,156,161,175,188,196,299,321,367,411,416,1075,1079,1171 'query-guide.md':414 'query-invalidation.md':436 'query-performance.md':431 'query-typescript.md':442 'querycli':166,171,173,187,265,711,712,725,728,739,1125 'queryclient.ensurequerydata':740 'queryclient.invalidatequeries':285 'queryclientprovid':167,185,407 'queryfn':205,333,344,388 'querykey':203,286,330,340,385 'queryopt':192,202,231,384,1068 'r':282 'r.json':283 'rc':783 'react':6,34,53,465,479 'react-queri':33 'reactquerydevtool':402,408 'recommend':198 'redirect':946 'refer':417,748,1037 'refetchmod':393 'refetchonwindowfocus':359 'regist':501 'render':524,1002,1057 'request':975 'requestmiddlewar':972 'res':208 'res.json':221 'res.ok':213 'reset':394 'resourc':1170 'respons':103 'retri':357 'return':184,220,242,245,248,288,645,699,904,949 'reusabl':195,1071 'rollback':429 'root':521,718 'root.tsx':520,708 'rout':19,40,67,111,119,134,508,515,522,528,544,633,673,703,715,727,734,767,768,895,1116,1120,1155,1163 'route.fullpath':648 'route.useloaderdata':698,903 'route.usesearch':643 'router':15,46,62,77,107,147,159,449,492,502,504,721,742,747,789,1176 'router-guide.md':745 'router-ssr.md':776 'router.ts':719 'routercontext':710 'routetre':487,494,723 'routing-patterns.md':765 'rpcs':131,838 'rsc':801 'run':912 'safe':5,50,114,130,553,837,1074 'schema':756 'scroll':100,425 'search':20,41,70,117,602,649,684,686,1100 'search-params.md':752 'searchschema':615,638 'secret':919,1140 'segment':532 'select':1053 'sendcontext':1047 'seo':988,1165 'serial':754 'server':26,38,57,80,126,792,833,839,914,936,979,1001,1147 'server-functions.md':1041 'server-on':1146 'server-routes.md':1058 'sessionid':387,392 'set':1086,1130 'setup':163,451,778,803 'share':757 'shellcompon':1055 'shouldreload':764 'singl':318 'skill' 'skill-tanstack' 'sort':313,623,642 'source-tenequm' 'spa':143,1005,1008 'split':122,774 'src/router.ts':481 'src/routes':511 'src/routes/__root.tsx':525 'src/routes/index.tsx':529 'src/start.ts':966 'ssr':25,79,763,777,791,981,1054 'ssr-modes.md':1052 'ssr/server':153 'ssr/ssg':125 'stabl':796 'stack':87,151,786 'staletim':176,353,432,1087 'standard':755 'start':24,47,75,124,155,157,782,1031,1036,1181 'start-guide.md':1034 'startinst':970 'state':39,58 'static':1024,1091 'strategi':439,775 'stream':101,366,762,779,1042 'streamedqueri':375,377,389 'streamfn':390 'string':273 'structur':1078 'style':566 'suspens':361 't.id':253 't.title':254 'tag':1169 'tanstack':1,9,44,160,448,781 'tanstack.com':1174,1179,1184 'tanstack.com/query/latest/docs/framework/react/overview':1173 'tanstack.com/router/latest/docs/framework/react/overview':1178 'tanstack.com/start/latest/docs/framework/react/overview':1183 'tanstack/react-query':169,194,261,379 'tanstack/react-query-devtools':399,404 'tanstack/react-router':456,485,499 'tanstack/react-start':852,930 'tanstack/react-start/plugin/vite':818 'tanstack/router-plugin':457 'tanstack/router-plugin/vite':471 'tanstack/start':807 'tanstack/zod-adapter':609 'tanstackrout':469,476 'tanstackstart':816,827,832,1007,1025 'throw':214,945 'time':847 'titl':272,292,1166 'todo':204,224,287,307,309,310,316 'todoid':317 'todolist':233 'todosqueryopt':201,239 'topic-agent-skills' 'topic-ai-agents' 'topic-claude-code' 'topic-claude-skills' 'topic-clawhub' 'topic-erc-8004' 'topic-mpp' 'topic-openclaw' 'topic-skills' 'topic-solana' 'topic-x402' 'tree':139 'trpc':104 'true':360,478,986,1010,1028,1030 'ts':458,600,809 'tsx':164,189,256,306,325,372,400,480,555,604,670,707,848,926,967 'tune':433 'type':4,49,113,129,228,443,552,597,666,836,934,962,1073,1090,1114 'type-saf':3,48,112,128,551,835,1072 'typeof':503 'ui':428 'undo':430 'updat':98 'url':547 'use':29,91,362,656,922,984,1067,1119,1143,1158 'useinfinitequeri':422 'usemut':258,269 'usenavig':579 'usequeri':191,238,329,339,383 'usequerycli':259,266 'user':328,331,342,346,349,902,906,907,940,944,952 'userlist':905 'usesuspensequeri':363 'v1':450 'v11':105 'v5':162 'valid':69,116,870,1099 'validatesearch':636 'via':965,1022,1104,1127 'view':563 'virtual':424,766 'vite':452,463,814 'vite.config.ts':459,810,1012 'vitejs/plugin-react':467,822 'vitereact':820,828 'wildcard':1061 'work':31 'worker':1015 'wrap':541 'write':644 'yet':802 'z':611,854 'z.enum':625 'z.number':619 'z.object':616,879 'z.string':881,883 'zod':613,661,856,1103 'zodvalid':606,637,1105","prices":[{"id":"f292959d-6486-43d4-95fe-384d5734dfd9","listingId":"0a0c8a1d-5169-4a08-92d4-04dacb299ca5","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"tenequm","category":"skills","install_from":"skills.sh"},"createdAt":"2026-04-18T23:05:30.415Z"}],"sources":[{"listingId":"0a0c8a1d-5169-4a08-92d4-04dacb299ca5","source":"github","sourceId":"tenequm/skills/tanstack","sourceUrl":"https://github.com/tenequm/skills/tree/main/skills/tanstack","isPrimary":false,"firstSeenAt":"2026-04-18T23:05:30.415Z","lastSeenAt":"2026-04-22T01:01:41.482Z"}],"details":{"listingId":"0a0c8a1d-5169-4a08-92d4-04dacb299ca5","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"tenequm","slug":"tanstack","github":{"repo":"tenequm/skills","stars":23,"topics":["agent-skills","ai-agents","claude-code","claude-skills","clawhub","erc-8004","mpp","openclaw","skills","solana","x402"],"license":"mit","html_url":"https://github.com/tenequm/skills","pushed_at":"2026-04-14T16:24:57Z","description":"Agent skills for building, shipping, and growing software products","skill_md_sha":"ff8ad1282b0085982f4ce8036a842b76ef91fc95","skill_md_path":"skills/tanstack/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/tenequm/skills/tree/main/skills/tanstack"},"layout":"multi","source":"github","category":"skills","frontmatter":{"name":"tanstack","description":"Build type-safe React apps with TanStack Query (data fetching, caching, mutations), Router (file-based routing, search params, loaders), and Start (SSR, server functions, middleware). Use when working with react-query, data fetching, server state, routing, search params, loaders, SSR, server functions, or full-stack React. Triggers on tanstack, react query, query client, useQuery, useMutation, invalidateQueries, tanstack router, file-based routing, search params, route loader, tanstack start, createServerFn, server functions, SSR."},"skills_sh_url":"https://skills.sh/tenequm/skills/tanstack"},"updatedAt":"2026-04-22T01:01:41.482Z"}}