[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EGAPZKWM5C369H1DMF5M9N":3,"skill-same:01M6EGAPZKWM5C369H1DMF5M9N":72},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":21,"linkOnly":22,"markdownContent":23,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":30,"ownerHtmlUrl":31,"ownerBlogUrl":6,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M6EGAPZKWM5C369H1DMF5M9N","tanstack-start",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Ftanstack-start\u002FSKILL.md",[],[18,19,20],"start","tanstack","tanstack start","2026-11-10 10:12:30",false,"# TanStack Start\n\n## Overview\n\nTanStack Start is a full-stack React framework built on TanStack Router and Vite. It provides type-safe server functions (`createServerFn`), file-based routing with loaders, composable middleware, Zod validation across the network boundary, and flexible rendering modes (SSR, SSG, SPA, ISR). Unlike Next.js, it uses Vite (not Webpack), supports any deployment target, and gives you explicit control over server\u002Fclient code boundaries.\n\n## Instructions\n\n### Step 1: Project Setup\n\n```bash\nnpx create-start@latest my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\n```text\nmy-app\u002F\n├── app\u002F\n│   ├── routes\u002F\n│   │   ├── __root.tsx          # Root layout\n│   │   ├── index.tsx           # \u002F route\n│   │   ├── about.tsx           # \u002Fabout route\n│   │   ├── posts\u002F\n│   │   │   ├── index.tsx       # \u002Fposts route\n│   │   │   └── $postId.tsx     # \u002Fposts\u002F:postId dynamic route\n│   │   └── api\u002F\n│   │       └── health.ts       # \u002Fapi\u002Fhealth server route\n│   ├── utils\u002F\n│   │   ├── posts.functions.ts  # Server function wrappers\n│   │   ├── posts.server.ts     # Server-only DB queries\n│   │   └── schemas.ts          # Shared Zod schemas\n│   ├── router.tsx\n│   └── client.tsx\n├── app.config.ts               # TanStack Start config\n└── package.json\n```\n\n### Step 2: Server Functions\n\nServer functions are the core primitive — define server-only logic callable from anywhere (loaders, components, event handlers). They cross the network boundary with full type safety.\n\n```typescript\n\u002F\u002F app\u002Futils\u002Fposts.server.ts — Server-only database queries\nimport { db } from '~\u002Fdb'\n\nexport async function findPosts(limit: number) {\n  return db.query.posts.findMany({\n    limit,\n    orderBy: (posts, { desc }) => [desc(posts.createdAt)],\n    with: { author: true },\n  })\n}\n\nexport async function findPostById(id: string) {\n  return db.query.posts.findFirst({\n    where: (posts, { eq }) => eq(posts.id, id),\n    with: { author: true, comments: { with: { author: true } } },\n  })\n}\n\nexport async function createPost(data: { title: string; content: string; authorId: string }) {\n  return db.insert(posts).values(data).returning()\n}\n```\n\n```typescript\n\u002F\u002F app\u002Futils\u002Fposts.functions.ts — Server functions with validation\nimport { createServerFn } from '@tanstack\u002Freact-start'\nimport { z } from 'zod'\nimport { findPosts, findPostById, createPost } from '.\u002Fposts.server'\n\n\u002F\u002F GET — fetch posts (callable from loaders and components)\nexport const getPosts = createServerFn({ method: 'GET' })\n  .inputValidator(z.object({ limit: z.number().min(1).max(100).default(20) }))\n  .handler(async ({ data }) => {\n    return findPosts(data.limit)\n  })\n\n\u002F\u002F GET — fetch single post\nexport const getPost = createServerFn({ method: 'GET' })\n  .inputValidator(z.object({ id: z.string().uuid() }))\n  .handler(async ({ data }) => {\n    const post = await findPostById(data.id)\n    if (!post) throw notFound()\n    return post\n  })\n\n\u002F\u002F POST — create post (requires auth via middleware)\nexport const createNewPost = createServerFn({ method: 'POST' })\n  .middleware([authMiddleware])\n  .inputValidator(z.object({\n    title: z.string().min(1).max(200),\n    content: z.string().min(1).max(50000),\n  }))\n  .handler(async ({ data, context }) => {\n    \u002F\u002F context.user comes from authMiddleware\n    return createPost({ ...data, authorId: context.user.id })\n  })\n```\n\n### Step 3: Routes with Loaders\n\n```tsx\n\u002F\u002F app\u002Froutes\u002Fposts\u002Findex.tsx — Posts list page with loader\nimport { createFileRoute } from '@tanstack\u002Freact-router'\nimport { getPosts } from '~\u002Futils\u002Fposts.functions'\n\nexport const Route = createFileRoute('\u002Fposts\u002F')({\n  \u002F\u002F Loader runs on the server during SSR, fetches data before render\n  loader: () => getPosts({ data: { limit: 20 } }),\n\n  component: PostsPage,\n})\n\nfunction PostsPage() {\n  const posts = Route.useLoaderData()\n\n  return (\n    \u003Cdiv>\n      \u003Ch1>Posts\u003C\u002Fh1>\n      \u003Cul>\n        {posts.map(post => (\n          \u003Cli key={post.id}>\n            \u003CLink to=\"\u002Fposts\u002F$postId\" params={{ postId: post.id }}>\n              {post.title}\n            \u003C\u002FLink>\n            \u003Cspan> by {post.author.name}\u003C\u002Fspan>\n          \u003C\u002Fli>\n        ))}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  )\n}\n```\n\n```tsx\n\u002F\u002F app\u002Froutes\u002Fposts\u002F$postId.tsx — Dynamic post page\nimport { createFileRoute, notFound } from '@tanstack\u002Freact-router'\nimport { getPost } from '~\u002Futils\u002Fposts.functions'\n\nexport const Route = createFileRoute('\u002Fposts\u002F$postId')({\n  loader: ({ params }) => getPost({ data: { id: params.postId } }),\n\n  \u002F\u002F Error boundary for not-found\n  notFoundComponent: () => \u003Cdiv>Post not found\u003C\u002Fdiv>,\n\n  component: PostPage,\n})\n\nfunction PostPage() {\n  const post = Route.useLoaderData()\n\n  return (\n    \u003Carticle>\n      \u003Ch1>{post.title}\u003C\u002Fh1>\n      \u003Cp>By {post.author.name} · {new Date(post.createdAt).toLocaleDateString()}\u003C\u002Fp>\n      \u003Cdiv dangerouslySetInnerHTML={{ __html: post.content }} \u002F>\n\n      \u003Ch2>Comments ({post.comments.length})\u003C\u002Fh2>\n      {post.comments.map(comment => (\n        \u003Cdiv key={comment.id}>\n          \u003Cstrong>{comment.author.name}\u003C\u002Fstrong>\n          \u003Cp>{comment.body}\u003C\u002Fp>\n        \u003C\u002Fdiv>\n      ))}\n    \u003C\u002Farticle>\n  )\n}\n```\n\n### Step 4: Middleware\n\nComposable middleware for auth, logging, rate limiting — chains execute in order with `next()`.\n\n```typescript\n\u002F\u002F app\u002Fmiddleware\u002Fauth.ts — Authentication middleware\nimport { createMiddleware } from '@tanstack\u002Freact-start'\nimport { redirect } from '@tanstack\u002Freact-router'\nimport { getRequestHeader } from '@tanstack\u002Freact-start\u002Fserver'\nimport { verifyToken } from '~\u002Futils\u002Fauth.server'\n\n\u002F\u002F Request middleware — runs on all server requests that use it\nexport const authMiddleware = createMiddleware()\n  .server(async ({ next }) => {\n    const token = getRequestHeader('Authorization')?.replace('Bearer ', '')\n\n    if (!token) {\n      throw redirect({ to: '\u002Flogin' })\n    }\n\n    const user = await verifyToken(token)\n    if (!user) {\n      throw redirect({ to: '\u002Flogin' })\n    }\n\n    \u002F\u002F Pass user to the next middleware \u002F server function via context\n    return next({ context: { user } })\n  })\n\n\u002F\u002F Logging middleware — logs request timing\nexport const loggingMiddleware = createMiddleware()\n  .server(async ({ next }) => {\n    const start = Date.now()\n    const result = await next()\n    console.log(`Request took ${Date.now() - start}ms`)\n    return result\n  })\n\n\u002F\u002F Compose middleware — auth depends on logging\nexport const protectedMiddleware = createMiddleware()\n  .middleware([loggingMiddleware, authMiddleware])\n  .server(async ({ next, context }) => {\n    \u002F\u002F context.user is available from authMiddleware\n    console.log(`Authenticated request from ${context.user.email}`)\n    return next()\n  })\n```\n\n### Step 5: Server Functions in Components\n\n```tsx\n\u002F\u002F app\u002Froutes\u002Fposts\u002Fnew.tsx — Form with server function mutation\nimport { createFileRoute, useNavigate } from '@tanstack\u002Freact-router'\nimport { useServerFn } from '@tanstack\u002Freact-start'\nimport { createNewPost } from '~\u002Futils\u002Fposts.functions'\n\nexport const Route = createFileRoute('\u002Fposts\u002Fnew')({\n  component: NewPostForm,\n})\n\nfunction NewPostForm() {\n  const navigate = useNavigate()\n  const createPost = useServerFn(createNewPost)\n\n  async function handleSubmit(e: React.FormEvent\u003CHTMLFormElement>) {\n    e.preventDefault()\n    const formData = new FormData(e.currentTarget)\n\n    const post = await createPost({\n      data: {\n        title: formData.get('title') as string,\n        content: formData.get('content') as string,\n      },\n    })\n\n    \u002F\u002F Navigate to the new post\n    navigate({ to: '\u002Fposts\u002F$postId', params: { postId: post.id } })\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput name=\"title\" placeholder=\"Post title\" required \u002F>\n      \u003Ctextarea name=\"content\" placeholder=\"Write your post...\" required rows={10} \u002F>\n      \u003Cbutton type=\"submit\">Publish\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n```\n\n### Step 6: Server Routes (API Endpoints)\n\n```typescript\n\u002F\u002F app\u002Froutes\u002Fapi\u002Fhealth.ts — API-only route (no React component)\nimport { createAPIFileRoute } from '@tanstack\u002Freact-start\u002Fapi'\n\nexport const APIRoute = createAPIFileRoute('\u002Fapi\u002Fhealth')({\n  GET: async ({ request }) => {\n    return Response.json({\n      status: 'ok',\n      timestamp: new Date().toISOString(),\n      version: process.env.APP_VERSION,\n    })\n  },\n})\n```\n\n```typescript\n\u002F\u002F app\u002Froutes\u002Fapi\u002Fwebhooks\u002Fstripe.ts — Webhook handler\nimport { createAPIFileRoute } from '@tanstack\u002Freact-start\u002Fapi'\n\nexport const APIRoute = createAPIFileRoute('\u002Fapi\u002Fwebhooks\u002Fstripe')({\n  POST: async ({ request }) => {\n    const signature = request.headers.get('stripe-signature')\n    const body = await request.text()\n\n    const event = stripe.webhooks.constructEvent(body, signature, process.env.STRIPE_WEBHOOK_SECRET)\n\n    switch (event.type) {\n      case 'checkout.session.completed':\n        await handleCheckoutComplete(event.data.object)\n        break\n      case 'customer.subscription.updated':\n        await handleSubscriptionUpdate(event.data.object)\n        break\n    }\n\n    return Response.json({ received: true })\n  },\n})\n```\n\n### Step 7: Rendering Modes\n\n```typescript\n\u002F\u002F app.config.ts — Configure rendering mode\nimport { defineConfig } from '@tanstack\u002Freact-start\u002Fconfig'\nimport vite from 'vite'\n\nexport default defineConfig({\n  vite: {\n    \u002F\u002F Vite config\n  },\n  \u002F\u002F Deploy targets\n  server: {\n    preset: 'node-server',        \u002F\u002F or 'cloudflare-pages', 'netlify', 'vercel'\n  },\n})\n```\n\n```tsx\n\u002F\u002F Static prerendering — generate at build time\n\u002F\u002F app\u002Froutes\u002Fabout.tsx\nexport const Route = createFileRoute('\u002Fabout')({\n  \u002F\u002F This page will be statically generated at build time\n  staticData: { prerender: true },\n  loader: () => getAboutContent(),\n  component: AboutPage,\n})\n\n\u002F\u002F Selective SSR — skip SSR for client-heavy pages\n\u002F\u002F app\u002Froutes\u002Fdashboard.tsx\nexport const Route = createFileRoute('\u002Fdashboard')({\n  \u002F\u002F This page will be a client-side SPA (no SSR)\n  ssr: false,\n  component: DashboardPage,\n})\n```\n\n## Guidelines\n\n- **Server functions are the network boundary** — `createServerFn` replaces API routes for most use cases. Server code stays on the server, client gets type-safe RPC stubs.\n- **File organization**: `.functions.ts` for server function wrappers, `.server.ts` for server-only helpers, `.ts` for shared schemas. Static imports of `.functions.ts` are safe anywhere.\n- **Loaders run before render** — data is available immediately in components via `Route.useLoaderData()`. No loading spinners for initial page data.\n- **Use `useServerFn()` hook** in components to call server functions with proper error handling and loading states.\n- **Middleware composes** — build auth, logging, rate limiting as independent middleware and chain them. Context flows through the chain via `next({ context })`.\n- **Zod validation in `inputValidator`** — validates on both client and server, single schema definition, full TypeScript inference.\n- **Deploy anywhere** — Vite-based build outputs for Node.js, Cloudflare Workers\u002FPages, Netlify, Vercel, Deno. Change the `server.preset` in config.\n- **TanStack Router underneath** — all router features work (type-safe links, search params, nested layouts, error boundaries, pending states).\n- **Use React Query for mutations** — combine `useServerFn` with `useMutation` for optimistic updates, error handling, and cache invalidation.\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Ftanstack-start",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill tanstack-start",{"tool":40,"command":41},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill tanstack-start",{"tool":43,"command":44},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill tanstack-start","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Ftanstack-start\u002FSKILL.md",true,[48,54,60,64,68],{"path":49,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":52,"sourceHtmlUrl":53},"push-notification-patterns.md","REFERENCE","参考文档",19818,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fclaude-code-apple-skills\u002Fskills\u002Fgenerators\u002Fpush-notifications\u002Fpush-notification-patterns.md",{"path":55,"resourceType":56,"resourceTypeDesc":57,"sizeBytes":58,"sourceHtmlUrl":59},"templates\u002FNotificationCategories.swift","OTHER","其他",6098,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fclaude-code-apple-skills\u002Fskills\u002Fgenerators\u002Fpush-notifications\u002Ftemplates\u002FNotificationCategories.swift",{"path":61,"resourceType":56,"resourceTypeDesc":57,"sizeBytes":62,"sourceHtmlUrl":63},"templates\u002FNotificationDelegate.swift",8750,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fclaude-code-apple-skills\u002Fskills\u002Fgenerators\u002Fpush-notifications\u002Ftemplates\u002FNotificationDelegate.swift",{"path":65,"resourceType":56,"resourceTypeDesc":57,"sizeBytes":66,"sourceHtmlUrl":67},"templates\u002FNotificationManager.swift",9392,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fclaude-code-apple-skills\u002Fskills\u002Fgenerators\u002Fpush-notifications\u002Ftemplates\u002FNotificationManager.swift",{"path":69,"resourceType":56,"resourceTypeDesc":57,"sizeBytes":70,"sourceHtmlUrl":71},"templates\u002FNotificationPayload.swift",6202,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fclaude-code-apple-skills\u002Fskills\u002Fgenerators\u002Fpush-notifications\u002Ftemplates\u002FNotificationPayload.swift",[73,87,97,106,112,119],{"skillNo":74,"name":75,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":83,"publishedAt":21},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[84,85,86],"model","model hierarchy","model hierarchy skill",{"skillNo":88,"name":89,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":93,"publishedAt":21},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[92],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},[94,95,96],"MCP","zoom","zoom mcp",{"skillNo":98,"name":99,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":21},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[103,104,105,95],"sdk","zoom apps sdk","apps",{"skillNo":107,"name":108,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":21},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[108],{"skillNo":113,"name":114,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":118,"publishedAt":21},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[117],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},[114],{"skillNo":120,"name":121,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":21},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[121]]