developers

Introducing the Auth0 SDK for TanStack Start

Meet the new Auth0 SDK for TanStack Start and learn how to use it to add authentication to your apps.

Oct 13, 2026 • 6 min read

TanStack Start has quickly become one of the most talked-about full-stack React frameworks, and until now, wiring up authentication meant hand-rolling OpenID Connect (OIDC) flows or adapting an SDK that was never built for it. That changes with @auth0/auth0-tanstack-start-react, a new SDK purpose-built for TanStack Start's server functions, middleware, and file-based router.

In this post, we will look at what the SDK gives you out of the box, and walk through adding login, logout, and a protected route to a TanStack Start app in a few minutes.

Why a Dedicated SDK

TanStack Start is not Next.js or Remix. It has its own conventions for middleware (createMiddleware), server functions (createServerFn), and route context (beforeLoad). A generic Node OIDC client can get you logged in, but it will not give you typed router context, route guards that plug into beforeLoad, or session helpers that work inside TanStack Start's server functions. The new SDK was built against those primitives directly, so authentication state flows through the router the same way your loader data does.

What You Get

The SDK ships a small, focused API surface:

  • Hooks: useAuth0, useUser, useOrg, useLogin, useLogout, useMfa
  • Components: SignedIn, SignedOut, HasOrg, AuthReady, AuthLoading - declarative conditional rendering based on auth state
  • Route guards: requireAuth and requireOrg for use in a route's beforeLoad
  • Server middleware: requireAuthMiddleware, withApiAuth, withApiScopes, withApiOrg, and claim-based guards like withApiClaimIncludes
  • Server helpers: getSession(auth0), getAccessToken(auth0), getTokenSet(auth0), createFetcher(auth0)

Auth routes (/auth/login, /auth/callback, /auth/logout, /auth/profile, /auth/backchannel-logout) are mounted automatically once the middleware is registered. There is no route handler file to write yourself.

Setup Auth0 for TanStack Start Apps

Let's see how to set up Auth0 for your StanStack Start application.

Install the Auth0 SDK for Tanstack Start

Execute the following command in your terminal where you have your Tanstack Start React app to install the Auth0 SDK:

npm install @auth0/auth0-tanstack-start-react

Peer dependencies are React 18 or 19, @tanstack/react-router, and @tanstack/react-start v1.

Configure environment variables

Create an Auth0 application (Regular Web App in Auth0 dashboard) and set the following as environment variables:

AUTH0_DOMAIN=YOUR_AUTH0_APP_DOMAIN
AUTH0_CLIENT_ID=YOUR_AUTH0_APP_CLIENT_ID
AUTH0_CLIENT_SECRET=YOUR_AUTH0_APP_CLIENT_SECRET
AUTH0_SECRET=YOUR_LONG_RANDOM_SECRET_HERE
APP_BASE_URL=http://localhost:3000

Generate AUTH0_SECRET with openssl rand -hex 32, and set your app's callback URL to http://localhost:3000/auth/callback.

Create the server-side Auth0 instance

Create a server side Auth0 instance to use Auth0 authentication in your TanStack app, as shown in the following code:

// src/auth.server.ts
import { auth0Server } from '@auth0/auth0-tanstack-start-react/server';

export const auth0 = auth0Server();

Register the middleware

Register the Auth0 specific middleware in your app to mount auth routes:

// src/start.ts
import { createStart } from '@tanstack/react-start';
import { auth0Middleware } from '@auth0/auth0-tanstack-start-react/server/middleware';

export const startInstance = createStart(() => ({
  requestMiddleware: [auth0Middleware()],
}));

Import from /server/middleware, not the /server barrel, in start.ts. That file runs in both the client and server bundles, and pulling in the full /server module here will break the client build.

Wire up router context and the provider

In the router.tsx file, include auth0RouterContext to access Auth0 router context across routes:

// src/router.tsx
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
import { auth0RouterContext } from '@auth0/auth0-tanstack-start-react/client';
import type { Auth0RouterContext } from '@auth0/auth0-tanstack-start-react/types';
import { routeTree } from './routeTree.gen';

export interface RouterContext {
  auth0: Auth0RouterContext;
}

export function getRouter() {
  return createTanStackRouter({
    routeTree,
    context: { auth0: auth0RouterContext } satisfies RouterContext,
  });
}

declare module '@tanstack/react-router' {
  interface Register {
    router: ReturnType<typeof getRouter>;
  }
}

Next, update your root route file to wire up the Auth0 router context and wrap your application in the Auth0Provider. This ensures authentication state is properly initialized and available across all routes:

// src/routes/__root.tsx
import { createRootRouteWithContext } from '@tanstack/react-router';
import { Auth0Provider, auth0BeforeLoad } from '@auth0/auth0-tanstack-start-react/client';
import type { RouterContext } from '../router';

export const Route = createRootRouteWithContext<RouterContext>()({
  beforeLoad: auth0BeforeLoad(),
  shellComponent: RootDocument,
});

function RootDocument({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Auth0Provider>{children}</Auth0Provider>
      </body>
    </html>
  );
}

Add login and logout

Add login and logout support for your application as shown inn the following examples.

The following code snippet implements a login butto:

// src/components/LoginButton.tsx
import { useLogin } from '@auth0/auth0-tanstack-start-react/client';

export function LoginButton() {
  const login = useLogin();
  return <button onClick={() => login('/dashboard')}>Log In</button>;
}

Here is the logout button implementation:

// src/components/LogoutButton.tsx
import { useLogout } from '@auth0/auth0-tanstack-start-react/client';

export function LogoutButton() {
  const logout = useLogout();
  return <button onClick={() => logout()}>Log Out</button>;
}

useLogin and useLogout trigger a full browser navigation rather than a client-side router transition, since the auth routes they hit are handled on the server.

Protect a route

Use requireAuth to protect a route in your app, as shown below:

// src/routes/dashboard.tsx
import { createFileRoute } from '@tanstack/react-router';
import { requireAuth, useUser } from '@auth0/auth0-tanstack-start-react/client';

export const Route = createFileRoute('/dashboard')({
  beforeLoad: requireAuth({ returnTo: '/dashboard' }),
  component: Dashboard,
});

function Dashboard() {
  const user = useUser();
  return <h1>Welcome, {user?.name}!</h1>;
}

requireAuth runs in beforeLoad, that is, before the route's loader or component ever execute. An unauthenticated visitor is redirected to log in and sent back to /dashboard afterward.

Reading the Session on the Server

Server functions and API routes reach the session through the free functions exported from /server, passing your auth0 instance as the first argument:

import { createServerFn } from '@tanstack/react-start';
import { getSession, getAccessToken } from '@auth0/auth0-tanstack-start-react/server';
import { auth0 } from '../auth.server';

const getMyOrders = createServerFn().handler(async () => {
  const session = await getSession(auth0);
  const token = await getAccessToken(auth0);
  // call your API with `token`, scoped to `session.user`
});

If you are coming from another Auth0 SDK, note the shape: it is getSession(auth0), not auth0.getSession().

Beyond the Basics

The SDK's examples directory includes a passkeys app alongside the basic OIDC example, showing how to layer WebAuthn-based passwordless login on top of the same session model. Organizations, MFA, and API scope checks (withApiOrg, withApiScopes) are available through the same middleware and guard pattern shown above, so adding them does not mean learning a new mental model, just a new guard.

Try It

The fastest way to see it end to end is the official quickstart, which scaffolds a fresh TanStack Start app and adds the SDK step by step. For the full API surface, including the middleware and server-helper reference, see the SDK README on GitHub.

If you do not already have an Auth0 account yet, create one for free.

About the author

Rengarajan R

Rengarajan R

Technical Product Manager

Rengarajan is a Technical Product Management at Okta, overseeing the Auth0 SDKs and Developer Tools. Based in Bangalore and drawing on his past experience at Catalyst by Zoho and Sony, Rengarajan is passionate about building secure dev tools and provider better experience for Developers and AI Agents.View profile