TanStack Start Quickstart
TanStack Start is a new React framework currently in the Release Candidate stage. You can use it today but there may be bugs or breaking changes before a stable release.
To get setup quickly with Convex and TanStack Start run
npm create convex@latest -- -t tanstack-start
or follow the guide below.
To use an auth provider with Convex and TanStack Start, see the TanStack Start + Clerk guide or the TanStack Start + WorkOS AuthKit guide.
Learn how to query data from Convex in a TanStack Start site.
- Create a TanStack Start site
Create a TanStack Start app using the
create-start-appcommand:npx create-start-app@latest - Install the Convex client and server library
To get started with Convex install the
convexpackage and a few React Query-related packages.npm install convex @convex-dev/react-query @tanstack/react-router-ssr-query @tanstack/react-query - Update src/routes/__root.tsx
Add a
QueryClientto the router context to make React Query usable anywhere in the TanStack Start site.src/routes/__root.tsximport { QueryClient } from "@tanstack/react-query";
import { createRootRouteWithContext } from "@tanstack/react-router";
import { Outlet, Scripts, HeadContent } from "@tanstack/react-router";
import * as React from "react";
export const Route = createRootRouteWithContext<{
queryClient: QueryClient;
}>()({
head: () => ({
meta: [
{
charSet: "utf-8",
},
{
name: "viewport",
content: "width=device-width, initial-scale=1",
},
{
title: "TanStack Start Starter",
},
],
}),
component: RootComponent,
});
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
);
}
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
<HeadContent />
</head>
<body>
{children}
<Scripts />
</body>
</html>
);
} - Update src/router.tsx
Replace the file
src/router.tsxwith these contents.This creates a
ConvexClientand aConvexQueryClientand wires in aConvexProvider.src/router.tsximport { createRouter } from "@tanstack/react-router";
import { QueryClient } from "@tanstack/react-query";
import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { ConvexProvider } from "convex/react";
import { routeTree } from "./routeTree.gen";
export function getRouter() {
const CONVEX_URL = (import.meta as any).env.VITE_CONVEX_URL!;
if (!CONVEX_URL) {
console.error("missing envar VITE_CONVEX_URL");
}
const convexQueryClient = new ConvexQueryClient(CONVEX_URL);
const queryClient: QueryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: convexQueryClient.hashFn(),
queryFn: convexQueryClient.queryFn(),
},
},
});
convexQueryClient.connect(queryClient);
const router = createRouter({
routeTree,
defaultPreload: "intent",
context: { queryClient },
scrollRestoration: true,
Wrap: ({ children }) => (
<ConvexProvider client={convexQueryClient.convexClient}>
{children}
</ConvexProvider>
),
});
setupRouterSsrQueryIntegration({ router, queryClient });
return router;
} - Set up a Convex dev deployment
Next, run
npx convex dev. This will prompt you to log in with GitHub, create a project, and save your production and deployment URLs.It will also create a
convex/folder for you to write your backend API functions in. Thedevcommand will then continue running to sync your functions with your dev deployment in the cloud.npx convex dev - Create sample data for your database
In a new terminal window, create a
sampleData.jsonlfile with some sample data.sampleData.jsonl{"text": "Buy groceries", "isCompleted": true}
{"text": "Go for a swim", "isCompleted": true}
{"text": "Integrate Convex", "isCompleted": false} - Add the sample data to your database
Now that your project is ready, add a
taskstable with the sample data into your Convex database with theimportcommand.npx convex import --table tasks sampleData.jsonl - Expose a database query
Add a new file
tasks.tsin theconvex/folder with a query function that loads the data.Exporting a query function from this file declares an API function named after the file and the export name,
api.tasks.get.convex/tasks.tsimport { query } from "./_generated/server";
export const get = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("tasks").collect();
},
}); - Display the data in your app
Replace the file
src/routes/index.tsxwith these contents.The
useSuspenseQueryhook renders the API functionapi.tasks.getquery result on the server initially, then it updates live in the browser.src/routes/index.tsximport { convexQuery } from "@convex-dev/react-query";
import { useSuspenseQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { api } from "../../convex/_generated/api";
export const Route = createFileRoute("/")({
component: Home,
});
function Home() {
const { data } = useSuspenseQuery(convexQuery(api.tasks.get, {}));
return (
<div>
{data.map(({ _id, text }) => (
<div key={_id}>{text}</div>
))}
</div>
);
} - Start the app
Start the app, open http://localhost:3000 in a browser, and see the list of tasks.
npm run dev
For more see the TanStack Start with Convex client documentation page.