Skip to content

examples: add tanstack start with better auth example#6352

Open
MrHertal wants to merge 7 commits into
TanStack:mainfrom
MrHertal:examples/start-basic-better-auth
Open

examples: add tanstack start with better auth example#6352
MrHertal wants to merge 7 commits into
TanStack:mainfrom
MrHertal:examples/start-basic-better-auth

Conversation

@MrHertal

@MrHertal MrHertal commented Jan 10, 2026

Copy link
Copy Markdown

This pull request introduces a new example project, start-basic-better-auth, demonstrating authentication integration between TanStack Start and Better Auth using GitHub OAuth. The project includes all necessary configuration, routing, authentication logic, and supporting documentation. It provides a ready-to-use template for developers to implement secure authentication and protected routes in a React application.

Authentication and Session Management:

  • Implements Better Auth server configuration in src/utils/auth.ts, enabling GitHub OAuth and stateless session management via cookies.
  • Sets up the Better Auth client in src/utils/auth-client.ts for use in React components.
  • Adds an API handler route for /api/auth/* to process authentication requests through Better Auth.

Routing and Protected Pages:

  • Defines the root route and context in src/routes/__root.tsx, fetching the session and providing navigation with sign-in/sign-out logic.
  • Implements protected and login routes (src/routes/protected.tsx and src/routes/login.tsx) that redirect users based on authentication status. [1] [2]
  • Generates the route tree and router setup, including custom error and not-found boundaries. [1] [2]

Project Structure and Tooling:

  • Provides a complete package.json with dependencies for TanStack Router/Start, Better Auth, React 19, Tailwind CSS, and Vite tooling.
  • Adds TypeScript configuration (tsconfig.json) and environment variable example (.env.example) for easy setup and development. [1] [2]
  • Includes .gitignore to exclude build artifacts and sensitive files.

Documentation and UI Components:

  • Adds a comprehensive README.md with setup instructions, OAuth configuration steps, and key file references for authentication integration.
  • Implements reusable UI components for error handling (DefaultCatchBoundary.tsx), not found pages (NotFound.tsx), and applies Tailwind CSS styling. [1] [2] [3]
  • Sample pages display authentication status and session data for debugging and demonstration. [1] [2]

This example provides a robust starting point for secure authentication workflows in TanStack Start applications.

Summary by CodeRabbit

  • Documentation

    • Added comprehensive example project documentation with setup and authentication integration instructions.
  • New Features

    • New example project demonstrating React authentication with GitHub OAuth login, route protection, session management, and sign-in/sign-out functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 10, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a complete new example React + TanStack Start project demonstrating GitHub OAuth integration via Better Auth, including routing architecture, protected routes, session management, and environment configuration. No modifications to existing codebases; purely additive example scaffolding.

Changes

Cohort / File(s) Summary
Configuration & Tooling
.env.example, .gitignore, package.json, tsconfig.json, vite.config.ts
Project setup including environment variables (BETTER_AUTH_SECRET, GITHUB credentials), build dependencies, TypeScript strict mode, and Vite dev server on port 10000 with Tailwind/TanStack plugins.
Documentation
README.md
Project guide covering environment setup, GitHub OAuth App configuration (callback URLs: http://localhost:10000/api/auth/callback/github), installation, development/build commands, and key authentication files.
Router Configuration
src/router.tsx, src/routeTree.gen.ts
Router factory function and auto-generated route tree wiring together all routes with default error/not-found handlers and scroll restoration; includes typed route metadata and FileRoutesByPath module augmentation.
Root & API Routes
src/routes/__root.tsx, src/routes/api/auth/$.ts
Root layout with server-side session fetching, NavBar with sign-in/out flows, and catch-all API route handler delegating auth requests to better-auth middleware.
Page Routes
src/routes/index.tsx, src/routes/login.tsx, src/routes/protected.tsx
Home page displaying session/user info, GitHub OAuth sign-in page, and protected route with beforeLoad guard redirecting unauthenticated users to /login.
Components
src/components/DefaultCatchBoundary.tsx, src/components/NotFound.tsx
Error boundary with retry/navigation actions and 404 fallback component.
Utilities & Styling
src/utils/auth-client.ts, src/utils/auth.ts, src/styles/app.css
Authentication client instantiation, better-auth configuration with GitHub social provider and stateless cookie-based sessions, and Tailwind CSS import.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • TanStack/router#5847 — Adds similar TanStack Start example app with generated routeTree.gen.ts and getRouter implementation
  • TanStack/router#5849 — Adds another TanStack Start example with routeTree.gen.ts and router.tsx pattern

Suggested labels

documentation

Suggested reviewers

  • birkskyum
  • schiller-manuel

Poem

🐰 A rabbit hops through auth's green door,
With TanStack routes and sessions galore,
GitHub OAuth dancing with Tailwind's grace,
Protected pages in their rightful place—
Better Auth blooms in this example so fine! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'examples: add tanstack start with better auth example' directly and accurately summarizes the main change—adding a new example project demonstrating TanStack Start integration with Better Auth.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In @examples/react/start-basic-better-auth/package.json:
- Around line 1-32: Replace the pinned versions for the internal TanStack
packages so the example uses workspace packages: change the dependency entries
for "@tanstack/react-router", "@tanstack/react-router-devtools", and
"@tanstack/react-start" from their current "^1.147.0" values to "workspace:*" so
the example builds against the monorepo workspace versions.

In @examples/react/start-basic-better-auth/src/components/NotFound.tsx:
- Line 3: The children prop in the NotFound component is typed as any; update
the signature in export function NotFound({ children }: { children?: any }) to
use React.ReactNode instead (e.g., { children?: React.ReactNode }) and add the
appropriate import (either import React from 'react' or import type { ReactNode
} from 'react' and use ReactNode) so the file compiles under TypeScript strict
mode; keep the change scoped to the NotFound component signature and imports.

In @examples/react/start-basic-better-auth/src/routes/__root.tsx:
- Around line 81-85: The sign-out flow in handleSignOut lacks error handling;
wrap the async sequence (authClient.signOut, router.invalidate, router.navigate)
in a try/catch/finally: attempt signOut and only navigate on success, catch and
log the error (and surface user feedback via UI toast or set an error state) if
signOut fails, and call router.invalidate in finally to ensure client state is
refreshed regardless of outcome; reference handleSignOut, authClient.signOut,
router.invalidate, and router.navigate when making these changes.

In @examples/react/start-basic-better-auth/src/routes/protected.tsx:
- Around line 47-52: The code renders the entire session object via
JSON.stringify(session) which can leak sensitive tokens; update the JSX to avoid
printing full session: either gate the debug block behind a development-only
flag (e.g., process.env.NODE_ENV === "development") or replace
JSON.stringify(session, null, 2) with a redacted subset such as JSON.stringify({
user: { name: session?.user?.name, email: session?.user?.email } }, null, 2);
ensure you still reference the same session variable and keep the debug wrapper
conditional so it never shows in production.

In @examples/react/start-basic-better-auth/src/utils/auth.ts:
- Around line 10-11: Replace the non-null assertions for
process.env.GITHUB_CLIENT_ID and process.env.GITHUB_CLIENT_SECRET with a runtime
check that validates these env vars at startup: read
process.env.GITHUB_CLIENT_ID and process.env.GITHUB_CLIENT_SECRET into
variables, if either is missing throw or log a clear error (e.g.,
"GITHUB_CLIENT_ID is required") and exit, then use those validated variables for
clientId and clientSecret; reference the clientId/clientSecret fields in the
exported auth config (or the function that builds it) so the values are
guaranteed present.
- Around line 7-25: The Better Auth config in the exported auth (created via
betterAuth) is missing baseURL and trustedOrigins which breaks OAuth/CSRF in
production; update the betterAuth call for auth to include baseURL:
process.env.BETTER_AUTH_URL and trustedOrigins: [process.env.BETTER_AUTH_URL]
(or an array of allowed origins including localhost/dev and production URLs)
alongside the existing socialProviders and plugins, and then add the
corresponding BETTER_AUTH_URL (and any additional allowed origins) to your
environment files/.env.example.
🧹 Nitpick comments (11)
examples/react/start-basic-better-auth/.gitignore (1)

1-6: LGTM; consider widening env ignores to .env.* (while keeping .env.example).
Current rules are fine; if you want to prevent accidental commits of .env.development / .env.production, consider adding .env.* and a negation for .env.example.

examples/react/start-basic-better-auth/tsconfig.json (1)

1-24: Strict TS config looks good; consider adding forceConsistentCasingInFileNames.
This helps avoid case-only import bugs that show up on CI/Linux but not on macOS/Windows.

Proposed diff
 {
   "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,
+    "forceConsistentCasingInFileNames": true,
     "allowSyntheticDefaultImports": true,
     "baseUrl": ".",
     "paths": {
       "~/*": ["./src/*"]
     }
   },
   "include": ["src", "env.d.ts", "vite.config.ts"]
 }
examples/react/start-basic-better-auth/vite.config.ts (1)

9-10: Consider removing strictPort for better developer experience.

Setting strictPort: true will cause the dev server to fail immediately if port 10000 is already in use. For an example project, this might be overly strict and could frustrate developers who have other services running on that port. Consider removing this option or setting it to false to allow Vite to find an available port automatically.

♻️ More flexible configuration
  server: {
    port: 10000,
-    strictPort: true,
  },
examples/react/start-basic-better-auth/src/routes/__root.tsx (1)

100-105: Optional chaining is redundant within the conditional block.

Since routeContext.session is already verified as truthy on line 100, the optional chaining on routeContext.session?.user?.name and routeContext.session?.user?.email is redundant. While this doesn't cause issues, simplifying to routeContext.session.user?.name improves code clarity.

♻️ Simplify optional chaining
  {routeContext.session ? (
    <>
      <span className="text-gray-600">
-        {routeContext.session?.user?.name ||
-          routeContext.session?.user?.email}
+        {routeContext.session.user?.name ||
+          routeContext.session.user?.email}
      </span>
examples/react/start-basic-better-auth/.env.example (1)

1-3: Consider adding secret generation instructions.

The comment mentions the minimum length requirement, but developers might benefit from guidance on how to generate a secure secret. Consider adding a comment with a command they can run.

📝 Enhanced documentation
 # Better Auth Configuration
-BETTER_AUTH_SECRET=your-secret-key-here-min-32-chars-long
+# Generate a secure secret with: openssl rand -base64 32
+BETTER_AUTH_SECRET=your-secret-key-here-min-32-chars-long
examples/react/start-basic-better-auth/src/router.tsx (1)

11-12: Use consistent component reference pattern.

The defaultErrorComponent uses a direct component reference while defaultNotFoundComponent wraps the component in an inline arrow function. This inconsistency creates a new component instance on each evaluation and could interfere with hot module replacement during development.

♻️ Make component references consistent
    defaultPreload: "intent",
    defaultErrorComponent: DefaultCatchBoundary,
-    defaultNotFoundComponent: () => <NotFound />,
+    defaultNotFoundComponent: NotFound,
    scrollRestoration: true,
examples/react/start-basic-better-auth/src/routes/login.tsx (1)

14-19: Consider error handling for authentication failures.

The authClient.signIn.social() call has no error handling. If the OAuth flow fails (network error, user denies permission, etc.), the user receives no feedback.

♻️ Recommended enhancement with error handling
 function Login() {
+  const [error, setError] = React.useState<string | null>(null);
+
   const handleGitHubSignIn = () => {
-    authClient.signIn.social({
-      provider: "github",
-      callbackURL: "/",
-    });
+    setError(null);
+    authClient.signIn.social({
+      provider: "github",
+      callbackURL: "/",
+    }).catch((err) => {
+      setError("Failed to sign in. Please try again.");
+      console.error("Sign-in error:", err);
+    });
   };

   return (
     <div className="max-w-md mx-auto mt-10">
       <h1 className="text-2xl font-bold mb-6 text-center">Sign In</h1>

+      {error && (
+        <div className="mb-4 p-3 bg-red-100 text-red-700 rounded">
+          {error}
+        </div>
+      )}
+
       <div className="space-y-4">
examples/react/start-basic-better-auth/src/routes/index.tsx (1)

27-33: Validate image URLs to prevent potential security risks.

The user avatar is rendered directly from user.image without validation. While GitHub OAuth typically returns trusted URLs, it's a good practice to validate image sources to prevent potential SSRF or content injection if the OAuth provider's data is compromised or the provider is changed.

Consider adding URL validation or using a Content Security Policy to restrict image sources to trusted domains (e.g., GitHub's CDN).

examples/react/start-basic-better-auth/src/routes/protected.tsx (2)

3-10: Preserve “return to” intent on auth redirect (better UX).
Right now unauthenticated users always land on /login with no way to return to /protected after signing in; consider passing a search param (e.g. next=/protected) and consuming it in the login flow.

Proposed change
 export const Route = createFileRoute("/protected")({
   beforeLoad: ({ context }) => {
     if (!context.session) {
-      throw redirect({ to: "/login" });
+      throw redirect({
+        to: "/login",
+        search: { next: "/protected" },
+      });
     }
   },
   component: Protected,
 });

33-41: Harden avatar rendering (privacy/perf).
Consider adding loading="lazy", referrerPolicy="no-referrer" (common for 3rd-party avatars), and explicit width/height to reduce layout shift.

examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (1)

39-48: Optional: make “Go Back” more robust when history is empty.
window.history.back() can no-op on first-entry pages; consider falling back to router.navigate({ to: '/' }) (or just let the Link navigate) when history.length <= 1.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fad5fdb and 99bd881.

📒 Files selected for processing (18)
  • examples/react/start-basic-better-auth/.env.example
  • examples/react/start-basic-better-auth/.gitignore
  • examples/react/start-basic-better-auth/README.md
  • examples/react/start-basic-better-auth/package.json
  • examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx
  • examples/react/start-basic-better-auth/src/components/NotFound.tsx
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
  • examples/react/start-basic-better-auth/src/router.tsx
  • examples/react/start-basic-better-auth/src/routes/__root.tsx
  • examples/react/start-basic-better-auth/src/routes/api/auth/$.ts
  • examples/react/start-basic-better-auth/src/routes/index.tsx
  • examples/react/start-basic-better-auth/src/routes/login.tsx
  • examples/react/start-basic-better-auth/src/routes/protected.tsx
  • examples/react/start-basic-better-auth/src/styles/app.css
  • examples/react/start-basic-better-auth/src/utils/auth-client.ts
  • examples/react/start-basic-better-auth/src/utils/auth.ts
  • examples/react/start-basic-better-auth/tsconfig.json
  • examples/react/start-basic-better-auth/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • examples/react/start-basic-better-auth/src/router.tsx
  • examples/react/start-basic-better-auth/src/routes/api/auth/$.ts
  • examples/react/start-basic-better-auth/src/routes/index.tsx
  • examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx
  • examples/react/start-basic-better-auth/src/utils/auth.ts
  • examples/react/start-basic-better-auth/src/routes/__root.tsx
  • examples/react/start-basic-better-auth/src/components/NotFound.tsx
  • examples/react/start-basic-better-auth/src/utils/auth-client.ts
  • examples/react/start-basic-better-auth/vite.config.ts
  • examples/react/start-basic-better-auth/src/routes/protected.tsx
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
  • examples/react/start-basic-better-auth/src/routes/login.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • examples/react/start-basic-better-auth/src/router.tsx
  • examples/react/start-basic-better-auth/src/routes/api/auth/$.ts
  • examples/react/start-basic-better-auth/src/routes/index.tsx
  • examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx
  • examples/react/start-basic-better-auth/src/utils/auth.ts
  • examples/react/start-basic-better-auth/src/routes/__root.tsx
  • examples/react/start-basic-better-auth/src/components/NotFound.tsx
  • examples/react/start-basic-better-auth/src/utils/auth-client.ts
  • examples/react/start-basic-better-auth/vite.config.ts
  • examples/react/start-basic-better-auth/src/routes/protected.tsx
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
  • examples/react/start-basic-better-auth/src/routes/login.tsx
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

Use workspace protocol workspace:* for internal dependencies in package.json files

Files:

  • examples/react/start-basic-better-auth/package.json
🧠 Learnings (9)
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router

Applied to files:

  • examples/react/start-basic-better-auth/src/router.tsx
  • examples/react/start-basic-better-auth/src/routes/api/auth/$.ts
  • examples/react/start-basic-better-auth/src/routes/index.tsx
  • examples/react/start-basic-better-auth/src/routes/__root.tsx
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • examples/react/start-basic-better-auth/src/router.tsx
  • examples/react/start-basic-better-auth/src/routes/protected.tsx
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code

Applied to files:

  • examples/react/start-basic-better-auth/tsconfig.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • examples/react/start-basic-better-auth/tsconfig.json
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
  • examples/react/start-basic-better-auth/package.json
📚 Learning: 2025-12-25T13:04:55.492Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 6215
File: e2e/react-start/custom-basepath/package.json:13-17
Timestamp: 2025-12-25T13:04:55.492Z
Learning: In the TanStack Router repository, e2e test scripts are specifically designed to run in CI (which uses a Unix environment), so Unix-specific commands (like `rm -rf`, `&` for backgrounding, and direct environment variable assignments without `cross-env`) are acceptable in e2e test npm scripts.

Applied to files:

  • examples/react/start-basic-better-auth/.gitignore
  • examples/react/start-basic-better-auth/package.json
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.

Applied to files:

  • examples/react/start-basic-better-auth/.gitignore
  • examples/react/start-basic-better-auth/src/routes/protected.tsx
  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.

Applied to files:

  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.

Applied to files:

  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions

Applied to files:

  • examples/react/start-basic-better-auth/src/routeTree.gen.ts
🧬 Code graph analysis (6)
examples/react/start-basic-better-auth/src/router.tsx (3)
examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (1)
  • DefaultCatchBoundary (10-53)
examples/react/start-basic-better-auth/src/components/NotFound.tsx (1)
  • NotFound (3-25)
examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
  • RouterContext (18-20)
examples/react/start-basic-better-auth/src/routes/api/auth/$.ts (5)
examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
  • Route (28-51)
examples/react/start-basic-better-auth/src/routes/index.tsx (1)
  • Route (3-5)
examples/react/start-basic-better-auth/src/routes/login.tsx (1)
  • Route (4-11)
examples/react/start-basic-better-auth/src/routes/protected.tsx (1)
  • Route (3-10)
examples/react/start-basic-better-auth/src/utils/auth.ts (1)
  • auth (7-25)
examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (3)
e2e/react-start/server-routes/src/components/DefaultCatchBoundary.tsx (1)
  • DefaultCatchBoundary (10-53)
examples/react/start-basic-cloudflare/src/components/DefaultCatchBoundary.tsx (1)
  • DefaultCatchBoundary (10-53)
examples/solid/start-basic-authjs/src/components/DefaultCatchBoundary.tsx (1)
  • DefaultCatchBoundary (10-53)
examples/react/start-basic-better-auth/src/routes/__root.tsx (7)
examples/react/start-basic-better-auth/src/utils/auth.ts (2)
  • AuthSession (28-28)
  • auth (7-25)
packages/start-server-core/src/request-response.ts (1)
  • getRequestHeaders (149-152)
examples/react/start-basic-better-auth/src/routes/api/auth/$.ts (1)
  • Route (8-15)
examples/react/start-basic-better-auth/src/routes/index.tsx (1)
  • Route (3-5)
examples/react/start-basic-better-auth/src/routes/login.tsx (1)
  • Route (4-11)
examples/react/start-basic-better-auth/src/routes/protected.tsx (1)
  • Route (3-10)
examples/react/start-basic-better-auth/src/utils/auth-client.ts (1)
  • authClient (3-3)
examples/react/start-basic-better-auth/src/routeTree.gen.ts (1)
examples/react/start-basic-better-auth/src/router.tsx (1)
  • getRouter (7-19)
examples/react/start-basic-better-auth/src/routes/login.tsx (5)
examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
  • Route (28-51)
examples/react/start-basic-better-auth/src/routes/index.tsx (1)
  • Route (3-5)
examples/react/start-basic-better-auth/src/routes/protected.tsx (1)
  • Route (3-10)
examples/react/start-basic-better-auth/src/utils/auth-client.ts (1)
  • authClient (3-3)
packages/router-core/src/route.ts (1)
  • path (1590-1592)
🔇 Additional comments (6)
examples/react/start-basic-better-auth/src/styles/app.css (1)

1-1: The @import "tailwindcss"; syntax is correct for Tailwind v4.1.18, which is the version specified in this project's package.json. No changes needed.

examples/react/start-basic-better-auth/src/utils/auth-client.ts (1)

1-3: No action required—createAuthClient() defaults are correct for this TanStack Start setup. The client is used only in browser context (onClick handlers, client components), and the server uses a separate auth instance. The default basePath of /api/auth matches your route configuration at routes/api/auth/$.ts, so explicit configuration is unnecessary.

examples/react/start-basic-better-auth/src/routes/__root.tsx (1)

22-26: LGTM! Clean server function implementation.

The session fetching logic correctly uses the server-side headers and Better Auth API. Errors naturally propagate to route error boundaries, which is the expected behavior in TanStack Router.

examples/react/start-basic-better-auth/src/routes/api/auth/$.ts (1)

8-15: LGTM! Standard Better Auth API route pattern.

The implementation correctly delegates all authentication requests to Better Auth's handler. This is the standard integration pattern and properly handles all auth-related endpoints under /api/auth/*.

examples/react/start-basic-better-auth/src/router.tsx (1)

14-16: LGTM! Type-safe context initialization.

The use of satisfies RouterContext ensures type safety while allowing TypeScript to infer the exact type. The initial session: null value will be properly populated by the root route's beforeLoad hook.

examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (1)

1-53: Matches existing TanStack Start examples; looks good.
Implementation aligns with the repo’s other DefaultCatchBoundary patterns (router invalidate + root-aware navigation).

Comment thread examples/react/start-basic-better-auth/package.json
Comment thread examples/react/start-basic-better-auth/src/components/NotFound.tsx Outdated
Comment thread examples/react/start-basic-better-auth/src/routes/__root.tsx Outdated
Comment thread examples/react/start-basic-better-auth/src/routes/protected.tsx
Comment thread examples/react/start-basic-better-auth/src/utils/auth.ts Outdated
Comment thread examples/react/start-basic-better-auth/src/utils/auth.ts Outdated
@MrHertal

Copy link
Copy Markdown
Author

I started from the Authjs example and adapted it for Better Auth.

@socket-security

socket-security Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedbetter-auth@​1.6.23981008596100

View full report

MrHertal added 4 commits July 11, 2026 11:29
…ress review feedback

- Bump internal @tanstack/* and tooling deps to match sibling examples (drop stale ^1.147.0)
- Remove unused tailwind-merge and switch to Vite's resolve.tsconfigPaths (drop vite-tsconfig-paths)
- auth: add baseURL + trustedOrigins for OAuth/CSRF; validate GitHub env vars instead of non-null assertions
- protected: redact debug session output to avoid leaking tokens
- root: add error handling to sign-out flow
- NotFound: type children as ReactNode instead of any
- tsconfig: fix include (drop non-existent env.d.ts)
- Format all files with Prettier (single quotes, no semicolons)
baseUrl is deprecated in TS 6 (TS5101) and unnecessary — paths resolve
relative to tsconfig. Matches sibling examples (start-basic, start-basic-authjs).
Adds the workspace importer entry and the better-auth@1.6.23 dependency
subtree. Purely additive (279 insertions, 0 deletions) — no unrelated
nightly/build-stack drift. Verified with a frozen-lockfile install and a
successful example build.
@MrHertal

Copy link
Copy Markdown
Author

Hi 👋 This PR adds a TanStack Start + Better Auth example (GitHub OAuth, protected routes, session in the router context). It's structured to mirror the existing examples/react/start-basic-authjs example, so it stays consistent with the current Start examples.

I believe it's ready for review:

  • ✅ Builds cleanly (client + SSR) via nx build, and tsc --noEmit passes under strict mode
  • better-auth on latest stable (1.6.23); other deps match the sibling examples
  • ✅ Uses Vite 8's resolve.tsconfigPaths instead of vite-tsconfig-paths (consistent with docs: update migrate from next docs to working example #7025)
  • ✅ Lockfile update is additive only (just the example importer + better-auth subtree — no unrelated churn)
  • ✅ All CodeRabbit review threads resolved

Two small asks:

  1. Could a maintainer approve the CI run? So far only the CodeRabbit/Socket checks have run (first-time contributor), so the build/test workflow hasn't executed yet — I'd love to get the checks green.
  2. Does a hand-written Start + Better Auth example fit your current direction for Start examples (I noticed some Start-example restructuring in docs: migrate Start example guidance to Builder and baselines #6698)? Happy to realign it however you'd prefer.

cc @Sheraff — saw you maintain the Solid start-convex-better-auth example, so this might be up your alley. No rush at all, just would really appreciate any feedback 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant