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.