sample/harness/tanstack-start/skills/tanstack-start/SKILL.md
Full-stack React framework powered by TanStack Router with SSR, streaming, server functions, and deployment to any hosting provider.
npx skillsauth add sc30gsw/claude-code-customes tanstack-startInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
TanStack Start is a full-stack React framework built on TanStack Router, powered by Vite and Nitro (via Vinxi). It provides server-side rendering, streaming, server functions (RPC), middleware, API routes, and deploys to any platform via Nitro presets.
Package: @tanstack/react-start
Router Plugin: @tanstack/router-plugin
Build Tool: Vinxi (Vite + Nitro)
Status: RC (Release Candidate)
RSC Support: React Server Components support is in active development and will land as a non-breaking v1.x addition
npx @tanstack/cli create my-app
# Or manually:
npm install @tanstack/react-start @tanstack/react-router react react-dom
npm install -D @tanstack/router-plugin typescript vite vite-tsconfig-paths
my-app/
app/
routes/
__root.tsx # Root layout
index.tsx # / route
posts.$postId.tsx # /posts/:postId
api/
users.ts # /api/users API route
client.tsx # Client entry
router.tsx # Router creation
ssr.tsx # SSR entry
routeTree.gen.ts # Auto-generated route tree
app.config.ts # TanStack Start config
tsconfig.json
package.json
app.config.ts)import { defineConfig } from "@tanstack/react-start/config";
import viteTsConfigPaths from "vite-tsconfig-paths";
export default defineConfig({
vite: {
plugins: [viteTsConfigPaths({ projects: ["./tsconfig.json"] })],
},
server: {
preset: "node-server", // 'vercel' | 'netlify' | 'cloudflare-pages' | etc.
},
tsr: {
appDirectory: "./app",
routesDirectory: "./app/routes",
generatedRouteTree: "./app/routeTree.gen.ts",
},
});
createServerFn)Server functions provide type-safe RPC calls between client and server.
import { createServerFn } from "@tanstack/react-start";
// GET (data fetching, cacheable)
const getUsers = createServerFn().handler(async () => {
const users = await db.query.users.findMany();
return users;
});
// POST (mutations, side effects)
const createUser = createServerFn({ method: "POST" })
.validator((data: { name: string; email: string }) => data)
.handler(async ({ data }) => {
const user = await db.insert(users).values(data).returning();
return user;
});
import { z } from "zod";
const updateUser = createServerFn({ method: "POST" })
.validator(
z.object({
id: z.string(),
name: z.string().min(1),
email: z.string().email(),
}),
)
.handler(async ({ data }) => {
// data is fully typed: { id: string; name: string; email: string }
return await db.update(users).set(data).where(eq(users.id, data.id));
});
import { createMiddleware } from "@tanstack/react-start";
const loggingMiddleware = createMiddleware().handler(async ({ next }) => {
console.log("Request started");
const result = await next();
console.log("Request completed");
return result;
});
const authMiddleware = createMiddleware().handler(async ({ next }) => {
const request = getWebRequest();
const session = await getSession(request);
if (!session?.user) {
throw redirect({ to: "/login" });
}
// Pass typed context to handler
return next({ context: { user: session.user } });
});
const adminMiddleware = createMiddleware()
.middleware([authMiddleware])
.handler(async ({ next, context }) => {
// context.user is typed from authMiddleware
if (context.user.role !== "admin") {
throw redirect({ to: "/unauthorized" });
}
return next({ context: { isAdmin: true } });
});
// Usage
const adminAction = createServerFn({ method: "POST" })
.middleware([adminMiddleware])
.handler(async ({ context }) => {
// context: { user: User; isAdmin: boolean }
return { success: true };
});
// app/routes/api/users.ts
import { createAPIFileRoute } from "@tanstack/react-start/api";
export const APIRoute = createAPIFileRoute("/api/users")({
GET: async ({ request }) => {
const users = await db.query.users.findMany();
return Response.json(users);
},
POST: async ({ request }) => {
const body = await request.json();
const user = await db.insert(users).values(body).returning();
return new Response(JSON.stringify(user), { status: 201 });
},
});
export const Route = createFileRoute('/dashboard')({
loader: async () => ({
criticalData: await fetchCriticalData(),
deferredData: defer(fetchSlowData()),
}),
component: Dashboard,
})
function Dashboard() {
const { criticalData, deferredData } = Route.useLoaderData()
return (
<div>
<CriticalSection data={criticalData} />
<Suspense fallback={<Loading />}>
<Await promise={deferredData}>
{(data) => <SlowSection data={data} />}
</Await>
</Suspense>
</div>
)
}
// app.config.ts
export default defineConfig({
server: {
preset: "node-server", // Self-hosted Node.js
// preset: 'vercel', // Vercel
// preset: 'netlify', // Netlify
// preset: 'cloudflare-pages', // Cloudflare Pages
// preset: 'aws-lambda', // AWS Lambda
// preset: 'deno-server', // Deno Deploy
// preset: 'bun', // Bun
},
});
createServerFn GET for data fetching (cacheable, preloadable)createServerFn POST for mutations and side effectsbeforeLoad for route-level auth guardsdefer() for non-critical data to improve TTFBdefaultPreload: 'intent' on the router for instant navigationawait in loaders leads to streaming issuesdeclare module '@tanstack/react-router' loses all type safetytools
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
testing
# sdd-workflow — Workflow Status Dashboard ## Slash Command ``` /sdd-workflow [slug] ``` ## Purpose Read-only meta skill. Displays the current state of the SDD workflow — which phases are complete, which is next, and any blockers. Does NOT modify any files. --- ## This Skill is Read-Only `sdd-workflow` never writes to or modifies any file. It only reads spec files and git history to report status. There is no approval gate for this skill. --- ## Usage: Specific Feature ``` /sdd-workflo
content-media
# sdd-tasks **Slash command**: `/sdd-tasks <slug>` **Purpose**: Generate `tasks.md` (TASK-001..N) and `progress.md` from `requirements.md` and `design.md`. --- ## Prerequisites - `.claude/specs/<slug>/requirements.md` must exist - `.claude/specs/<slug>/design.md` must exist (run `/sdd-design` first) --- ## Steps ### 1. Read spec inputs ``` .claude/specs/<slug>/requirements.md .claude/specs/<slug>/design.md ``` Extract: - Every REQ-XXX ID with its acceptance criteria - Every design sect
development
# sdd-review — Post-Implementation Code Review ## Slash Command ``` /sdd-review <slug> ``` ## Purpose Run code review and security review on all changes introduced by the feature branch. Append structured findings to `review.md`. Does NOT auto-apply fixes — only proposes them. --- ## Prerequisites - `sdd-impl` has completed: all tasks in `progress.md` are `done` (or at least one is `done`; partial reviews are allowed). - The feature branch must have at least one commit ahead of `main`. -