diff --git a/examples/react/start-basic-better-auth/.env.example b/examples/react/start-basic-better-auth/.env.example
new file mode 100644
index 0000000000..6fb0f1821f
--- /dev/null
+++ b/examples/react/start-basic-better-auth/.env.example
@@ -0,0 +1,9 @@
+# Better Auth Configuration
+BETTER_AUTH_SECRET=your-secret-key-here-min-32-chars-long
+
+# Better Auth URL (base URL, no /api/auth suffix)
+BETTER_AUTH_URL=http://localhost:10000
+
+# GitHub OAuth Configuration (https://github.com/settings/developers)
+GITHUB_CLIENT_ID=your-github-client-id
+GITHUB_CLIENT_SECRET=your-github-client-secret
diff --git a/examples/react/start-basic-better-auth/.gitignore b/examples/react/start-basic-better-auth/.gitignore
new file mode 100644
index 0000000000..3479e16707
--- /dev/null
+++ b/examples/react/start-basic-better-auth/.gitignore
@@ -0,0 +1,6 @@
+node_modules
+dist
+.env
+*.local
+.DS_Store
+.tanstack
diff --git a/examples/react/start-basic-better-auth/README.md b/examples/react/start-basic-better-auth/README.md
new file mode 100644
index 0000000000..fc15980da7
--- /dev/null
+++ b/examples/react/start-basic-better-auth/README.md
@@ -0,0 +1,66 @@
+# TanStack Start - Better Auth Example
+
+A TanStack Start example demonstrating authentication with Better Auth.
+
+- [TanStack Router Docs](https://tanstack.com/router)
+- [Better Auth Documentation](https://www.better-auth.com/)
+
+## Start a new project based on this example
+
+To start a new project based on this example, run:
+
+```sh
+npx gitpick TanStack/router/tree/main/examples/react/start-basic-better-auth start-basic-better-auth
+```
+
+## Setup
+
+This example requires environment variables for Better Auth configuration. Copy the `.env.example` file to `.env` and fill in your GitHub OAuth credentials:
+
+```sh
+cp .env.example .env
+```
+
+### GitHub OAuth Setup
+
+1. Go to [GitHub Developer Settings](https://github.com/settings/developers)
+2. Click "New OAuth App"
+3. Fill in:
+ - Application name: Your app name
+ - Homepage URL: `http://localhost:10000`
+ - Authorization callback URL: `http://localhost:10000/api/auth/callback/github`
+4. Copy the Client ID and Client Secret to your `.env` file
+
+## Getting Started
+
+From your terminal:
+
+```sh
+pnpm install
+pnpm dev
+```
+
+This starts your app in development mode, rebuilding assets on file changes.
+
+## Build
+
+To build the app for production:
+
+```sh
+pnpm build
+```
+
+## Authentication Configuration
+
+This example demonstrates how to integrate Better Auth with TanStack Start. Check the source code for examples of:
+
+- Configuring social authentication providers
+- Protecting routes with authentication
+- Accessing session data in server functions
+
+### Key Files
+
+- `src/utils/auth.ts` - Better Auth server configuration
+- `src/utils/auth-client.ts` - Better Auth client setup
+- `src/routes/__root.tsx` - Session fetching and navigation
+- `src/routes/protected.tsx` - Example of a protected route
diff --git a/examples/react/start-basic-better-auth/package.json b/examples/react/start-basic-better-auth/package.json
new file mode 100644
index 0000000000..eec836df46
--- /dev/null
+++ b/examples/react/start-basic-better-auth/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "tanstack-start-example-basic-better-auth",
+ "private": true,
+ "sideEffects": false,
+ "type": "module",
+ "scripts": {
+ "dev": "vite dev",
+ "build": "vite build",
+ "preview": "vite preview",
+ "start": "pnpx srvx --prod -s ../client dist/server/server.js"
+ },
+ "dependencies": {
+ "@tanstack/react-router": "^1.147.0",
+ "@tanstack/react-router-devtools": "^1.147.0",
+ "@tanstack/react-start": "^1.147.0",
+ "better-auth": "^1.4.10",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "tailwind-merge": "^2.6.0"
+ },
+ "devDependencies": {
+ "@tailwindcss/vite": "^4.1.18",
+ "@types/node": "^22.5.4",
+ "@types/react": "^19.0.8",
+ "@types/react-dom": "^19.0.3",
+ "@vitejs/plugin-react": "^4.6.0",
+ "tailwindcss": "^4.1.18",
+ "typescript": "^5.7.2",
+ "vite": "^7.1.7",
+ "vite-tsconfig-paths": "^5.1.4"
+ }
+}
diff --git a/examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx b/examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx
new file mode 100644
index 0000000000..2b0e48c6c8
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx
@@ -0,0 +1,53 @@
+import {
+ ErrorComponent,
+ Link,
+ rootRouteId,
+ useMatch,
+ useRouter,
+} from "@tanstack/react-router";
+import type { ErrorComponentProps } from "@tanstack/react-router";
+
+export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
+ const router = useRouter();
+ const isRoot = useMatch({
+ strict: false,
+ select: (state) => state.id === rootRouteId,
+ });
+
+ console.error("DefaultCatchBoundary Error:", error);
+
+ return (
+
+
+
+
+ {isRoot ? (
+
+ Home
+
+ ) : (
+ {
+ e.preventDefault();
+ window.history.back();
+ }}
+ >
+ Go Back
+
+ )}
+
+
+ );
+}
diff --git a/examples/react/start-basic-better-auth/src/components/NotFound.tsx b/examples/react/start-basic-better-auth/src/components/NotFound.tsx
new file mode 100644
index 0000000000..f22fabddca
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/components/NotFound.tsx
@@ -0,0 +1,25 @@
+import { Link } from "@tanstack/react-router";
+
+export function NotFound({ children }: { children?: any }) {
+ return (
+
+
+ {children ||
The page you are looking for does not exist.
}
+
+
+
+
+ Start Over
+
+
+
+ );
+}
diff --git a/examples/react/start-basic-better-auth/src/routeTree.gen.ts b/examples/react/start-basic-better-auth/src/routeTree.gen.ts
new file mode 100644
index 0000000000..2f59e4ba33
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/routeTree.gen.ts
@@ -0,0 +1,122 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
+
+import { Route as rootRouteImport } from './routes/__root'
+import { Route as ProtectedRouteImport } from './routes/protected'
+import { Route as LoginRouteImport } from './routes/login'
+import { Route as IndexRouteImport } from './routes/index'
+import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
+
+const ProtectedRoute = ProtectedRouteImport.update({
+ id: '/protected',
+ path: '/protected',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const LoginRoute = LoginRouteImport.update({
+ id: '/login',
+ path: '/login',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const IndexRoute = IndexRouteImport.update({
+ id: '/',
+ path: '/',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
+ id: '/api/auth/$',
+ path: '/api/auth/$',
+ getParentRoute: () => rootRouteImport,
+} as any)
+
+export interface FileRoutesByFullPath {
+ '/': typeof IndexRoute
+ '/login': typeof LoginRoute
+ '/protected': typeof ProtectedRoute
+ '/api/auth/$': typeof ApiAuthSplatRoute
+}
+export interface FileRoutesByTo {
+ '/': typeof IndexRoute
+ '/login': typeof LoginRoute
+ '/protected': typeof ProtectedRoute
+ '/api/auth/$': typeof ApiAuthSplatRoute
+}
+export interface FileRoutesById {
+ __root__: typeof rootRouteImport
+ '/': typeof IndexRoute
+ '/login': typeof LoginRoute
+ '/protected': typeof ProtectedRoute
+ '/api/auth/$': typeof ApiAuthSplatRoute
+}
+export interface FileRouteTypes {
+ fileRoutesByFullPath: FileRoutesByFullPath
+ fullPaths: '/' | '/login' | '/protected' | '/api/auth/$'
+ fileRoutesByTo: FileRoutesByTo
+ to: '/' | '/login' | '/protected' | '/api/auth/$'
+ id: '__root__' | '/' | '/login' | '/protected' | '/api/auth/$'
+ fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+ IndexRoute: typeof IndexRoute
+ LoginRoute: typeof LoginRoute
+ ProtectedRoute: typeof ProtectedRoute
+ ApiAuthSplatRoute: typeof ApiAuthSplatRoute
+}
+
+declare module '@tanstack/react-router' {
+ interface FileRoutesByPath {
+ '/protected': {
+ id: '/protected'
+ path: '/protected'
+ fullPath: '/protected'
+ preLoaderRoute: typeof ProtectedRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/login': {
+ id: '/login'
+ path: '/login'
+ fullPath: '/login'
+ preLoaderRoute: typeof LoginRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/': {
+ id: '/'
+ path: '/'
+ fullPath: '/'
+ preLoaderRoute: typeof IndexRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/api/auth/$': {
+ id: '/api/auth/$'
+ path: '/api/auth/$'
+ fullPath: '/api/auth/$'
+ preLoaderRoute: typeof ApiAuthSplatRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ }
+}
+
+const rootRouteChildren: RootRouteChildren = {
+ IndexRoute: IndexRoute,
+ LoginRoute: LoginRoute,
+ ProtectedRoute: ProtectedRoute,
+ ApiAuthSplatRoute: ApiAuthSplatRoute,
+}
+export const routeTree = rootRouteImport
+ ._addFileChildren(rootRouteChildren)
+ ._addFileTypes()
+
+import type { getRouter } from './router.tsx'
+import type { createStart } from '@tanstack/react-start'
+declare module '@tanstack/react-start' {
+ interface Register {
+ ssr: true
+ router: Awaited>
+ }
+}
diff --git a/examples/react/start-basic-better-auth/src/router.tsx b/examples/react/start-basic-better-auth/src/router.tsx
new file mode 100644
index 0000000000..338900bf6f
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/router.tsx
@@ -0,0 +1,19 @@
+import { createRouter } from "@tanstack/react-router";
+import { routeTree } from "./routeTree.gen";
+import { DefaultCatchBoundary } from "./components/DefaultCatchBoundary";
+import { NotFound } from "./components/NotFound";
+import type { RouterContext } from "./routes/__root";
+
+export function getRouter() {
+ const router = createRouter({
+ routeTree,
+ defaultPreload: "intent",
+ defaultErrorComponent: DefaultCatchBoundary,
+ defaultNotFoundComponent: () => ,
+ scrollRestoration: true,
+ context: {
+ session: null,
+ } satisfies RouterContext,
+ });
+ return router;
+}
diff --git a/examples/react/start-basic-better-auth/src/routes/__root.tsx b/examples/react/start-basic-better-auth/src/routes/__root.tsx
new file mode 100644
index 0000000000..ff38c30e0c
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/routes/__root.tsx
@@ -0,0 +1,125 @@
+///
+import type { ReactNode } from "react";
+import {
+ HeadContent,
+ Link,
+ Outlet,
+ Scripts,
+ createRootRouteWithContext,
+ useRouter,
+} from "@tanstack/react-router";
+import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
+import { createServerFn } from "@tanstack/react-start";
+import { getRequestHeaders } from "@tanstack/react-start/server";
+import { auth, type AuthSession } from "~/utils/auth";
+import { authClient } from "~/utils/auth-client";
+import appCss from "~/styles/app.css?url";
+
+export interface RouterContext {
+ session: AuthSession | null;
+}
+
+const fetchSession = createServerFn({ method: "GET" }).handler(async () => {
+ const headers = getRequestHeaders();
+ const session = await auth.api.getSession({ headers });
+ return session;
+});
+
+export const Route = createRootRouteWithContext()({
+ beforeLoad: async () => {
+ const session = await fetchSession();
+ return {
+ session,
+ };
+ },
+ head: () => ({
+ meta: [
+ {
+ charSet: "utf-8",
+ },
+ {
+ name: "viewport",
+ content: "width=device-width, initial-scale=1",
+ },
+ {
+ title: "TanStack Start Auth Example",
+ },
+ ],
+ links: [{ rel: "stylesheet", href: appCss }],
+ }),
+ component: RootComponent,
+});
+
+function RootComponent() {
+ return (
+
+
+
+ );
+}
+
+function RootDocument({ children }: { children: ReactNode }) {
+ return (
+
+
+
+
+
+
+ {children}
+
+
+
+
+ );
+}
+
+function NavBar() {
+ const router = useRouter();
+ const routeContext = Route.useRouteContext();
+
+ const handleSignOut = async () => {
+ await authClient.signOut();
+ await router.invalidate();
+ await router.navigate({ to: "/" });
+ };
+
+ return (
+
+ );
+}
diff --git a/examples/react/start-basic-better-auth/src/routes/api/auth/$.ts b/examples/react/start-basic-better-auth/src/routes/api/auth/$.ts
new file mode 100644
index 0000000000..79a36b6164
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/routes/api/auth/$.ts
@@ -0,0 +1,15 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { auth } from "~/utils/auth";
+
+/**
+ * Better Auth API route handler
+ * Handles all auth routes: /api/auth/*
+ */
+export const Route = createFileRoute("/api/auth/$")({
+ server: {
+ handlers: {
+ GET: ({ request }) => auth.handler(request),
+ POST: ({ request }) => auth.handler(request),
+ },
+ },
+});
diff --git a/examples/react/start-basic-better-auth/src/routes/index.tsx b/examples/react/start-basic-better-auth/src/routes/index.tsx
new file mode 100644
index 0000000000..afc0c137f2
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/routes/index.tsx
@@ -0,0 +1,50 @@
+import { createFileRoute } from "@tanstack/react-router";
+
+export const Route = createFileRoute("/")({
+ component: Home,
+});
+
+function Home() {
+ const { session } = Route.useRouteContext();
+ const user = session?.user;
+
+ return (
+
+
+ TanStack Start Better Auth Example
+
+
+ This example demonstrates Better Auth integration with TanStack Start
+ using GitHub OAuth.
+
+
+
+
Auth Status
+
+ {session ? (
+
+
Authenticated
+ {user?.image && (
+

+ )}
+
+ Name: {user?.name ?? "N/A"}
+
+
+ Email: {user?.email ?? "N/A"}
+
+
+ ) : (
+
+ You are not signed in. Click "Sign In" in the navigation bar to
+ authenticate with GitHub.
+
+ )}
+
+
+ );
+}
diff --git a/examples/react/start-basic-better-auth/src/routes/login.tsx b/examples/react/start-basic-better-auth/src/routes/login.tsx
new file mode 100644
index 0000000000..9f67a0bd78
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/routes/login.tsx
@@ -0,0 +1,43 @@
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import { authClient } from "~/utils/auth-client";
+
+export const Route = createFileRoute("/login")({
+ beforeLoad: ({ context }) => {
+ if (context.session) {
+ throw redirect({ to: "/" });
+ }
+ },
+ component: Login,
+});
+
+function Login() {
+ const handleGitHubSignIn = () => {
+ authClient.signIn.social({
+ provider: "github",
+ callbackURL: "/",
+ });
+ };
+
+ return (
+
+
Sign In
+
+
+
+
+
+ You'll be redirected to GitHub to complete the sign-in process.
+
+
+
+ );
+}
diff --git a/examples/react/start-basic-better-auth/src/routes/protected.tsx b/examples/react/start-basic-better-auth/src/routes/protected.tsx
new file mode 100644
index 0000000000..05e8ebd83c
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/routes/protected.tsx
@@ -0,0 +1,55 @@
+import { createFileRoute, redirect } from "@tanstack/react-router";
+
+export const Route = createFileRoute("/protected")({
+ beforeLoad: ({ context }) => {
+ if (!context.session) {
+ throw redirect({ to: "/login" });
+ }
+ },
+ component: Protected,
+});
+
+function Protected() {
+ const { session } = Route.useRouteContext();
+ const user = session?.user;
+
+ return (
+
+
Protected Page
+
+ This page is only accessible to authenticated users.
+
+
+
+
+ Welcome, {user?.name ?? "User"}!
+
+
+ {user && (
+
+
+ Email: {user?.email ?? "N/A"}
+
+ {user?.image && (
+
+
Avatar:
+

+
+ )}
+
+ )}
+
+
+
+
Session Data (Debug)
+
+ {JSON.stringify(session, null, 2)}
+
+
+
+ );
+}
diff --git a/examples/react/start-basic-better-auth/src/styles/app.css b/examples/react/start-basic-better-auth/src/styles/app.css
new file mode 100644
index 0000000000..f1d8c73cdc
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/styles/app.css
@@ -0,0 +1 @@
+@import "tailwindcss";
diff --git a/examples/react/start-basic-better-auth/src/utils/auth-client.ts b/examples/react/start-basic-better-auth/src/utils/auth-client.ts
new file mode 100644
index 0000000000..f1012dd4ac
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/utils/auth-client.ts
@@ -0,0 +1,3 @@
+import { createAuthClient } from "better-auth/react";
+
+export const authClient = createAuthClient();
diff --git a/examples/react/start-basic-better-auth/src/utils/auth.ts b/examples/react/start-basic-better-auth/src/utils/auth.ts
new file mode 100644
index 0000000000..05cf771468
--- /dev/null
+++ b/examples/react/start-basic-better-auth/src/utils/auth.ts
@@ -0,0 +1,28 @@
+import { betterAuth } from "better-auth";
+import { tanstackStartCookies } from "better-auth/tanstack-start";
+
+/**
+ * Better Auth configuration for TanStack Start with GitHub
+ */
+export const auth = betterAuth({
+ socialProviders: {
+ github: {
+ clientId: process.env.GITHUB_CLIENT_ID!,
+ clientSecret: process.env.GITHUB_CLIENT_SECRET!,
+ },
+ },
+ plugins: [
+ // Must be last plugin in the array
+ tanstackStartCookies(),
+ ],
+ // Stateless sessions (no database required)
+ session: {
+ cookieCache: {
+ enabled: true,
+ maxAge: 60 * 60 * 24 * 7,
+ },
+ },
+});
+
+// Export session type for use in router context
+export type AuthSession = typeof auth.$Infer.Session;
diff --git a/examples/react/start-basic-better-auth/tsconfig.json b/examples/react/start-basic-better-auth/tsconfig.json
new file mode 100644
index 0000000000..70cbbc5ce3
--- /dev/null
+++ b/examples/react/start-basic-better-auth/tsconfig.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "allowSyntheticDefaultImports": true,
+ "baseUrl": ".",
+ "paths": {
+ "~/*": ["./src/*"]
+ }
+ },
+ "include": ["src", "env.d.ts", "vite.config.ts"]
+}
diff --git a/examples/react/start-basic-better-auth/vite.config.ts b/examples/react/start-basic-better-auth/vite.config.ts
new file mode 100644
index 0000000000..3a326e95cf
--- /dev/null
+++ b/examples/react/start-basic-better-auth/vite.config.ts
@@ -0,0 +1,20 @@
+import { tanstackStart } from "@tanstack/react-start/plugin/vite";
+import { defineConfig } from "vite";
+import tsConfigPaths from "vite-tsconfig-paths";
+import viteReact from "@vitejs/plugin-react";
+import tailwindcss from "@tailwindcss/vite";
+
+export default defineConfig({
+ server: {
+ port: 10000,
+ strictPort: true,
+ },
+ plugins: [
+ tailwindcss(),
+ tsConfigPaths({
+ projects: ["./tsconfig.json"],
+ }),
+ tanstackStart(),
+ viteReact(),
+ ],
+});