Source: https://www.hype-stack.dev/docs/packs-templates/packs/starter-saas-betterauth

# SaaS Starter (Better Auth)

Authentication, organizations, roles, sessions, feature flags, and an admin app, powered by
[Better Auth](https://www.better-auth.com) on your own Postgres. This is the `starter-saas-betterauth` pack, and the
default starter. Unlike WorkOS, Better Auth is a self-hosted library, so there's no separate account to create. You
bring your own Google OAuth app.

```bash
npx @hype-stack/cli compose --packs starter-saas-betterauth,layout-basic
```

## What you get

- Email/password and Google sign-in, password reset, email verification
- Organizations: create, switch, invite members by email, roles and CASL permissions enforced with `hasAccess`
- An onboarding flow for users with no organization yet
- Per-organization [feature flags](/docs/backend/organizations#feature-flags), with an admin tab to override them
- A settings page with profile and organization tabs that feature packs extend
- The full [admin app](/docs/packs-templates/packs/admin): users, organizations, dashboard rows, admin management
- Mobile and browser-extension slots with the auth screens, the organization switcher, and settings
- The organization switcher and menu are contributed to the layout's shell action areas, so they render in every layout

Starting from the free [auth starter](/docs/packs-templates/packs/starter-auth-betterauth) instead? Swapping to this one
later is a family swap with no migration.

For session flow, middleware, and route guards, see [Authentication](/docs/backend/authentication) and
[Organizations](/docs/backend/organizations).

## What you need

- A **Google OAuth** web app you create in Google Cloud Console. Better Auth talks to Google directly.
- **Resend** for transactional email (password reset, email verification). Uses the base template's `RESEND_API_KEY`.
- Postgres and Valkey (base services).

## Register a Google OAuth app

1. Open [Google Cloud Console > APIs & Services > Credentials](https://console.cloud.google.com/apis/credentials).
2. Create an **OAuth 2.0 Client ID** of type **Web application**.
3. Under **Authorized redirect URIs**, add the Better Auth callback path:

```
http://localhost:3000/api/auth/callback/google
```

4. Copy the **Client ID** and **Client secret** into `apps/backend/.env` as `GOOGLE_CLIENT_ID` and
   `GOOGLE_CLIENT_SECRET`.

In production, add your deployed origin as well:

```
https://yourdomain.com/api/auth/callback/google
```

The path is fixed: Better Auth owns the handler at `/api/auth/*`, and the Google callback is always
`/api/auth/callback/google` appended to your `BETTER_AUTH_URL`.

## Environment variables

| Variable                    | Purpose                                                                                 |
| --------------------------- | --------------------------------------------------------------------------------------- |
| `BETTER_AUTH_URL`           | Origin Better Auth runs on (e.g. `http://localhost:3000`)                               |
| `BETTER_AUTH_SECRET`        | Auth secret. The CLI generates one at install time                                      |
| `GOOGLE_CLIENT_ID`          | Google OAuth client ID                                                                  |
| `GOOGLE_CLIENT_SECRET`      | Google OAuth client secret                                                              |
| `MOBILE_OAUTH_REDIRECT_URL` | Deep link the Expo app returns to after Google sign-in (default `hypestack://callback`) |
| `RESEND_API_KEY`            | Transactional email (password reset, verification)                                      |
| `SUPER_ADMIN_EMAIL`         | Bootstrap admin emails for the admin app                                                |

## Google sign-in flow

The pack starts Google sign-in from `GET /auth/google/:intent`, which calls Better Auth's `signInSocial`. After Google
redirects back to `/api/auth/callback/google`, Better Auth exchanges the code, creates the session, and sends the
browser to `/` (or `/onboarding` if the user has no organization).

## Admin app

This starter also ships a separate [admin app](/docs/packs-templates/packs/admin) for managing users and organizations.
Set `SUPER_ADMIN_EMAIL` in `apps/backend/.env` to sign in the first time.
