TanStack Start is a new full-stack React framework built on TanStack Router and Nitro. It combines type-safe routing, server functions, and SSR/SSG into one framework — with the same quality as TanStack Query.
Why TanStack Start?
- Type-safe routing — routes are fully typed, including params and search
- Server functions — call server code from client, RPC-style
- Nitro-powered — deploy to 20+ platforms
- TanStack Router — the best router in React ecosystem
- File-based routing — with full type inference
Quick Start
npm create @tanstack/start my-app
cd my-app
npm install
npm run dev
File-Based Routes (Type-Safe)
// routes/index.tsx
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/')({
component: HomePage,
});
function HomePage() {
return <h1>Welcome to TanStack Start!</h1>;
}
// routes/users/$userId.tsx
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/users/$userId')({
loader: async ({ params }) => {
// params.userId is typed as string!
const user = await fetchUser(params.userId);
return { user };
},
component: UserPage,
});
function UserPage() {
const { user } = Route.useLoaderData();
return <div>{user.name}</div>; // Fully typed!
}
Server Functions
import { createServerFn } from '@tanstack/start';
import { z } from 'zod';
// Runs on server, callable from client
const getUsers = createServerFn('GET', async () => {
const users = await db.select().from(usersTable);
return users;
});
const createUser = createServerFn('POST', async (input: { name: string; email: string }) => {
const user = await db.insert(usersTable).values(input).returning();
return user[0];
});
// Use in component
function UserList() {
const users = Route.useLoaderData(); // From loader
async function handleCreate() {
const newUser = await createUser({ name: 'Alice', email: 'alice@example.com' });
// Automatically revalidates
}
return (
<div>
{users.map(u => <div key={u.id}>{u.name}</div>)}
<button onClick={handleCreate}>Add User</button>
</div>
);
}
Search Params (Type-Safe)
import { createFileRoute } from '@tanstack/react-router';
import { z } from 'zod';
const searchSchema = z.object({
page: z.number().default(1),
sort: z.enum(['name', 'date', 'popular']).default('date'),
q: z.string().optional(),
});
export const Route = createFileRoute('/articles')({
validateSearch: searchSchema,
loader: async ({ search }) => {
// search.page, search.sort, search.q — all typed!
return fetchArticles(search);
},
component: ArticlesPage,
});
function ArticlesPage() {
const { page, sort, q } = Route.useSearch(); // Typed!
const navigate = Route.useNavigate();
return (
<div>
<button onClick={() => navigate({ search: { sort: 'popular' } })}>
Sort by Popular
</button>
</div>
);
}
Key Features
| Feature | Details |
|---|---|
| Routing | File-based, fully type-safe |
| Server | Server functions (RPC) |
| SSR | Streaming SSR + SSG |
| Deploy | Nitro → 20+ platforms |
| Data | Integrated with TanStack Query |
| Types | End-to-end, params + search + data |
Resources
Building React apps? Check my Apify actors or email spinov001@gmail.com.
Top comments (0)