Authentication deep dive
How Better Auth is wired up across the @repo/auth package, the Hono API, and the React Router frontend.
Authentication in LaunchApp is handled by Better Auth, a framework-agnostic auth library that supports email/password, OAuth providers, magic links, and more. The server instance lives in @repo/auth and is shared across both the Hono API and the React Router frontend — one config, one source of truth.
The API side
On the API side, the Better Auth handler is mounted under /api/auth/* in packages/api/src/app.ts. Every incoming request to that prefix is forwarded directly to Better Auth, which manages sessions via secure HTTP-only cookies.
app.on(["POST", "GET"], "/api/auth/**", (c) => auth.handler(c.req.raw));
Because the handler is mounted at a prefix rather than individual routes, adding new auth flows (social login, passkeys, 2FA) is a config-only change inside @repo/auth — the API mount stays the same.
The frontend side
The frontend uses the Better Auth client exported from @repo/auth. React Router loaders call auth.api.getSession({ headers: request.headers }) on the server to check whether the current user is authenticated before rendering a protected page.
Session data flows from the loader into the component via useLoaderData. Protected layouts like the dashboard redirect to /auth/login when no session is present, keeping the auth guard logic in one place rather than scattered across individual routes.
Adding a new provider
Adding a new OAuth provider (say GitHub) is a three-step change:
- Register the provider in the Better Auth config inside
@repo/auth. - Add the client ID and secret to
.envand.env.example. - Update the login page to show the new sign-in button.
The rest of the session handling — cookie setting, redirect after callback, session refresh — is automatic. The same provider then works across the Next.js, Nuxt, and SvelteKit variants because they all import from the same @repo/auth package.
What's different from DIY auth
Rolling your own auth means writing password hashing, session tokens, CSRF protection, OAuth state verification, rate limiting, and recovery flows. Each one is a subtle security footgun. Better Auth consolidates all of that behind a typed API, which is why LaunchApp ships it as the default rather than a hand-rolled middleware.