| 1 | # Cloudflare Better Auth |
| 2 | |
| 3 | Executable companion to the [six-part Better Auth tutorial](https://alchemy.run/better-auth/tutorial/part-1). |
| 4 | |
| 5 | ## Run locally |
| 6 | |
| 7 | From the repository root: |
| 8 | |
| 9 | ```sh |
| 10 | pnpm install |
| 11 | cd examples/cloudflare-better-auth |
| 12 | bun run dev |
| 13 | ``` |
| 14 | |
| 15 | Use a [configured Cloudflare profile](https://alchemy.run/cloudflare/setup). Alchemy chooses an available port and prints the URL; the local Worker and D1 run without provisioning cloud resources. |
| 16 | |
| 17 | Open that URL, create an account, and sign out and back in. The page displays the current user and the protected API response without exposing session tokens. |
| 18 | |
| 19 | ## Verify the HTTP flow |
| 20 | |
| 21 | In another terminal in this example directory, paste the printed URL after `read` and press Enter: |
| 22 | |
| 23 | ```sh |
| 24 | read -r BETTER_AUTH_TEST_URL |
| 25 | export BETTER_AUTH_TEST_URL |
| 26 | timeout 60 bun test |
| 27 | ``` |
| 28 | |
| 29 | The test creates a disposable account and checks cookies, sessions, public access, and sign-out rejection. Use a disposable database rather than production. |
| 30 | |
| 31 | ## Enable GitHub |
| 32 | |
| 33 | ```sh |
| 34 | cp .env.example .env |
| 35 | ``` |
| 36 | |
| 37 | Replace the dummy credentials with your GitHub OAuth application's values and enable the provider: |
| 38 | |
| 39 | ```dotenv |
| 40 | GITHUB_ENABLED=true |
| 41 | GITHUB_CLIENT_ID=your-oauth-client-id |
| 42 | GITHUB_CLIENT_SECRET=your-oauth-client-secret |
| 43 | ``` |
| 44 | |
| 45 | Use the running application's origin to construct the registered callback: |
| 46 | |
| 47 | ```sh |
| 48 | printf '%s/api/auth/callback/github\n' "$BETTER_AUTH_TEST_URL" |
| 49 | ``` |
| 50 | |
| 51 | Restart the dev command after configuration changes and check its printed URL. Update the registered callback if that URL changed; no fixed local port is required. |
| 52 | |
| 53 | The page shows the GitHub button only when enabled. The public provider endpoint exposes that flag, never credentials. |
| 54 | |
| 55 | ## Deploy |
| 56 | |
| 57 | ```sh |
| 58 | bun run deploy --stage production |
| 59 | ``` |
| 60 | |
| 61 | Use separate production OAuth credentials and register the deployed callback URL. Optionally set `AUTH_BASE_URL` to your production origin; leave it unset locally to use the incoming request's origin. |
| 62 | |
| 63 | Alchemy binds the database, migrates the schema, and preserves the generated signing secret through stack state. Keep that state for later deployments. |
| 64 | |
| 65 | ## Remove the deployment |
| 66 | |
| 67 | ```sh |
| 68 | bun run destroy --stage production |
| 69 | ``` |
| 70 | |
| 71 | Use the exact stage and profile of the deployment you intend to remove. The generated browser bundle in `public/ui.js` is ignored by Git. |