tanstack-start

TanStack Start Skills

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "tanstack-start" with this command: npx skills add tanstack-skills/tanstack-skills/tanstack-skills-tanstack-skills-tanstack-start

TanStack Start Skills

Overview

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

Installation & Project Setup

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

Project Structure

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

Configuration (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', }, })

Server Functions (createServerFn )

Server functions provide type-safe RPC calls between client and server.

Basic Server Functions

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 })

With Zod Validation

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)) })

Middleware

Creating Middleware

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 })

Auth Middleware with Context

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 } }) })

Chaining Middleware

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 } })

API Routes (Server Routes)

// 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 }) }, })

SSR Strategies

Streaming SSR (Default)

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> ) }

Deployment

Supported Platforms (Nitro Presets)

// 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 }, })

Best Practices

  • Use validators for all server function inputs - runtime safety and TypeScript inference

  • Compose middleware for cross-cutting concerns (auth, logging, rate limiting)

  • Use createServerFn GET for data fetching (cacheable, preloadable)

  • Use createServerFn POST for mutations and side effects

  • Use beforeLoad for route-level auth guards

  • Use defer() for non-critical data to improve TTFB

  • Set defaultPreload: 'intent' on the router for instant navigation

  • Co-locate server functions with the routes that use them

Common Pitfalls

  • Server functions cannot close over client-side variables (they're extracted to separate bundles)

  • Data returned from server functions must be serializable

  • Forgetting await in loaders leads to streaming issues

  • Importing server-only code in client bundles causes build errors

  • Missing declare module '@tanstack/react-router' loses all type safety

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

tanstack start

No summary provided by upstream source.

Repository SourceNeeds Review
-255
jezweb
General

tanstack-query

No summary provided by upstream source.

Repository SourceNeeds Review
General

tanstack-table

No summary provided by upstream source.

Repository SourceNeeds Review