--- title: 'Use Supabase with TanStack Start' subtitle: 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a TanStack Start app.' breadcrumb: 'Framework Quickstarts' --- <$Partial path="quickstart_db_setup.mdx" /> ## 3. Create a TanStack Start app Create a TanStack Start app using the official CLI. ```bash npx @tanstack/cli@latest create my-app ``` ## 4. Set up AI tooling (optional) <$Partial path="quickstart_ai_tooling.mdx" /> ## 5. Install the Supabase client libraries Navigate to the TanStack Start app and install `supabase-js` and `@supabase/ssr`, the helper package that manages cookie-based sessions for server-side rendering. ```bash cd my-app && npm install @supabase/supabase-js @supabase/ssr ``` ## 6. Declare Supabase environment variables Create a `.env.local` file in the root of your project and populate it with your Supabase connection variables. Get the values from the helper below, or [from the project **Connect** panel](/dashboard/project/_?showConnect=true&connectTab=frameworks&framework=tanstack). ```text name=.env.local VITE_SUPABASE_URL= VITE_SUPABASE_PUBLISHABLE_KEY= ``` <$Partial path="api_settings.mdx" variables={{ "framework": "tanstack", "tab": "frameworks" }} /> ## 7. Create Supabase client utilities TanStack Start needs two Supabase clients: a browser client for components that run in the browser, and a server client for loaders and server functions. Create a `src/lib/supabase` folder with a file for each client. Both clients read the same two variables, through the API available in each environment. The browser client uses `import.meta.env`, which Vite replaces at build time. The server client uses `process.env`, which the server runtime populates from your `.env.local` file. ```ts name=src/lib/supabase/client.ts /// import { createBrowserClient } from '@supabase/ssr' export function createClient() { return createBrowserClient( import.meta.env.VITE_SUPABASE_URL!, import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY! ) } ``` ```ts name=src/lib/supabase/server.ts import { createServerClient } from '@supabase/ssr' import { getCookies, setCookie, setResponseHeader } from '@tanstack/react-start/server' export function createClient() { return createServerClient( process.env.VITE_SUPABASE_URL!, process.env.VITE_SUPABASE_PUBLISHABLE_KEY!, { cookies: { getAll() { return Object.entries(getCookies()).map(([name, value]) => ({ name, value })) }, setAll(cookies, headers) { cookies.forEach(({ name, value, options }) => { setCookie(name, value, options) }) Object.entries(headers).forEach(([name, value]) => { setResponseHeader(name, value) }) }, }, } ) } ``` ## 8. Query Supabase data from TanStack Start Create a server function that queries the `instruments` table through the server client. TanStack Start's import protection blocks direct server imports in route files, so wrap the Supabase call in `createServerFn`. ```ts name=src/lib/supabase/fetch-instruments-server-fn.ts import { createServerFn } from '@tanstack/react-start' import { createClient } from '@/lib/supabase/server' export const fetchInstruments = createServerFn({ method: 'GET' }).handler(async () => { const supabase = createClient() const { data: instruments, error } = await supabase.from('instruments').select() if (error) { console.error(error) return { instruments: [], error: error.message } } return { instruments, error: null } }) ``` Replace the contents of `src/routes/index.tsx` with the following to call the server function from a route loader. The loader runs on the server, so the data is part of the initial server-rendered response. ```tsx name=src/routes/index.tsx import { createFileRoute } from '@tanstack/react-router' import { fetchInstruments } from '@/lib/supabase/fetch-instruments-server-fn' export const Route = createFileRoute('/')({ loader: async () => fetchInstruments(), component: Home, }) function Home() { const { instruments, error } = Route.useLoaderData() if (error) { return

Error loading instruments: {error}

} return (
    {instruments?.map((instrument) => (
  • {instrument.name}
  • ))}
) } ``` ## 9. Start the app Run the development server, go to http://localhost:3000 in a browser and you should see the list of instruments. ```bash npm run dev ``` <$Partial path="quickstart_going_to_production.mdx" /> ## Next steps - Learn how to [protect routes and check sessions](/docs/guides/auth/server-side/creating-a-client?queryGroups=framework&framework=tanstack) with the server client, or drop in a complete [sign-in and sign-up flow](/library/docs/tanstack/password-based-auth) from Supabase Library - [Insert more data](/docs/guides/database/import-data) into your database - Upload and serve static files using [Storage](/docs/guides/storage) - Explore [drop-in UI components](/ui) for your Supabase app