with one click
react-start
React bindings for TanStack Start: createStart, StartClient, StartServer, React-specific imports, re-exports from @tanstack/react-router, full project setup with React, useServerFn hook.
Menu
React bindings for TanStack Start: createStart, StartClient, StartServer, React-specific imports, re-exports from @tanstack/react-router, full project setup with React, useServerFn hook.
| name | react-start |
| description | React bindings for TanStack Start: createStart, StartClient, StartServer, React-specific imports, re-exports from @tanstack/react-router, full project setup with React, useServerFn hook. |
| type | framework |
| library | tanstack-start |
| library_version | 1.166.2 |
| framework | react |
| requires | ["start-core"] |
| sources | ["TanStack/router:packages/react-start/src","TanStack/router:docs/start/framework/react/build-from-scratch.md"] |
@tanstack/react-start)This skill builds on start-core. Read start-core first for foundational concepts.
This skill covers the React-specific bindings, setup, and patterns for TanStack Start.
For React Server Components patterns, see react-start/server-components.
CRITICAL: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use
createServerFnfor server-only logic.
CRITICAL: Do not confuse
@tanstack/react-startwith Next.js or Remix. They are completely different frameworks with different APIs.
CRITICAL: Types are FULLY INFERRED. Never cast, never annotate inferred values.
@tanstack/react-start re-exports everything from @tanstack/start-client-core plus:
useServerFn — React hook for calling server functions from componentsAll core APIs (createServerFn, createMiddleware, createStart, createIsomorphicFn, createServerOnlyFn, createClientOnlyFn) are available from @tanstack/react-start.
Server utilities (getRequest, getRequestHeader, setResponseHeader, setResponseHeaders, setResponseStatus) are imported from @tanstack/react-start/server.
npm i @tanstack/react-start @tanstack/react-router react react-dom
npm i -D vite @vitejs/plugin-react typescript @types/react @types/react-dom
{
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "node .output/server/index.mjs"
}
}
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "Bundler",
"module": "ESNext",
"target": "ES2022",
"skipLibCheck": true,
"strictNullChecks": true
}
}
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
tanstackStart(), // MUST come before react()
viteReact(),
],
})
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export function getRouter() {
const router = createRouter({
routeTree,
scrollRestoration: true,
})
return router
}
import type { ReactNode } from 'react'
import {
Outlet,
createRootRoute,
HeadContent,
Scripts,
} from '@tanstack/react-router'
export const Route = createRootRoute({
head: () => ({
meta: [
{ charSet: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ title: 'My TanStack Start App' },
],
}),
component: RootComponent,
})
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
)
}
function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
return (
<html>
<head>
<HeadContent />
</head>
<body>
{children}
<Scripts />
</body>
</html>
)
}
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
const getGreeting = createServerFn({ method: 'GET' }).handler(async () => {
return 'Hello from TanStack Start!'
})
export const Route = createFileRoute('/')({
loader: () => getGreeting(),
component: HomePage,
})
function HomePage() {
const greeting = Route.useLoaderData()
return <h1>{greeting}</h1>
}
Use useServerFn to call server functions from React components with proper integration:
import { createServerFn, useServerFn } from '@tanstack/react-start'
const updatePost = createServerFn({ method: 'POST' })
.validator((data: { id: string; title: string }) => data)
.handler(async ({ data }) => {
await db.posts.update(data.id, { title: data.title })
return { success: true }
})
function EditPostForm({ postId }: { postId: string }) {
const updatePostFn = useServerFn(updatePost)
const [title, setTitle] = useState('')
return (
<form
onSubmit={async (e) => {
e.preventDefault()
await updatePostFn({ data: { id: postId, title } })
}}
>
<input value={title} onChange={(e) => setTitle(e.target.value)} />
<button type="submit">Save</button>
</form>
)
}
import { createStart, createMiddleware } from '@tanstack/react-start'
const requestLogger = createMiddleware().server(async ({ next, request }) => {
console.log(`${request.method} ${request.url}`)
return next()
})
export const startInstance = createStart(() => ({
requestMiddleware: [requestLogger],
}))
All routing components from @tanstack/react-router work in Start:
<RouterProvider> — not needed in Start (handled automatically)<Outlet> — renders matched child route<Link> — type-safe navigation<Navigate> — declarative redirect<HeadContent> — renders head tags (must be in <head>)<Scripts> — renders body scripts (must be in <body>)<Await> — renders deferred data with Suspense<ClientOnly> — renders children only after hydration<CatchBoundary> — error boundaryAll hooks from @tanstack/react-router work in Start:
useRouter() — router instanceuseRouterState() — subscribe to router stateuseNavigate() — programmatic navigationuseSearch({ from }) — validated search paramsuseParams({ from }) — path paramsuseLoaderData({ from }) — loader datauseMatch({ from }) — full route matchuseRouteContext({ from }) — route contextRoute.useLoaderData() — typed loader data (preferred in route files)Route.useSearch() — typed search params (preferred in route files)// WRONG — this is the SPA router, NOT Start
import { createServerFn } from '@tanstack/react-router'
// CORRECT — server functions come from react-start
import { createServerFn } from '@tanstack/react-start'
// CORRECT — routing APIs come from react-router (re-exported by Start too)
import { createFileRoute, Link } from '@tanstack/react-router'
// WRONG — beforeLoad/loader are NOT React components
beforeLoad: () => {
const auth = useAuth() // React hook, cannot be used here
}
// CORRECT — pass state via router context
const rootRoute = createRootRouteWithContext<{ auth: AuthState }>()({})
Without <Scripts /> in the root route's <body>, client JavaScript doesn't load and the app won't hydrate.
Step-by-step migration from Next.js App Router to TanStack Start: route definition conversion, API mapping, server function conversion from Server Actions, middleware conversion, data fetching pattern changes.
Implement, review, debug, and refactor TanStack Start React Server Components in React 19 apps. Use when tasks mention @tanstack/react-start/rsc, renderServerComponent, createCompositeComponent, CompositeComponent, renderToReadableStream, createFromReadableStream, createFromFetch, Composite Components, React Flight streams, loader or query owned RSC caching, router.invalidate, structuralSharing: false, selective SSR, stale names like renderRsc or .validator, or migration from Next App Router RSC patterns. Do not use for generic SSR or non-TanStack RSC frameworks except brief comparison.
Solid bindings for TanStack Start: useServerFn hook, tanstackStart Vite plugin, StartClient, StartServer, Solid-specific setup, re-exports from @tanstack/start-client-core. Full project setup with Solid.
Server-side authentication primitives for TanStack Start: session cookies (HttpOnly, Secure, SameSite, __Host- prefix), session read/issue/destroy via createServerFn and middleware, OAuth authorization-code flow with state and PKCE, password-reset enumeration defense, CSRF for non-GET RPCs, rate limiting auth endpoints, session rotation on privilege change. Pairs with router-core/auth-and-guards for the routing side.
createMiddleware, request middleware (.server only), server function middleware (.client + .server), context passing via next({ context }), sendContext for client-server transfer, global middleware via createStart in src/start.ts, middleware factories, method order enforcement, fetch override precedence.
createServerFn (GET/POST), validator (Zod or function), useServerFn hook, server context utilities (getRequest, getRequestHeader, setResponseHeader, setResponseStatus), error handling (throw errors, redirect, notFound), streaming, FormData handling, file organization (.functions.ts, .server.ts).