1# Cloudflare Better Auth
2
3Executable companion to the [six-part Better Auth tutorial](https://alchemy.run/better-auth/tutorial/part-1).
4
5## Run locally
6
7From the repository root:
8
9```sh
10pnpm install
11cd examples/cloudflare-better-auth
12bun run dev
13```
14
15Use 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
17Open 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
21In another terminal in this example directory, paste the printed URL after `read` and press Enter:
22
23```sh
24read -r BETTER_AUTH_TEST_URL
25export BETTER_AUTH_TEST_URL
26timeout 60 bun test
27```
28
29The 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
34cp .env.example .env
35```
36
37Replace the dummy credentials with your GitHub OAuth application's values and enable the provider:
38
39```dotenv
40GITHUB_ENABLED=true
41GITHUB_CLIENT_ID=your-oauth-client-id
42GITHUB_CLIENT_SECRET=your-oauth-client-secret
43```
44
45Use the running application's origin to construct the registered callback:
46
47```sh
48printf '%s/api/auth/callback/github\n' "$BETTER_AUTH_TEST_URL"
49```
50
51Restart 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
53The page shows the GitHub button only when enabled. The public provider endpoint exposes that flag, never credentials.
54
55## Deploy
56
57```sh
58bun run deploy --stage production
59```
60
61Use 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
63Alchemy 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
68bun run destroy --stage production
69```
70
71Use the exact stage and profile of the deployment you intend to remove. The generated browser bundle in `public/ui.js` is ignored by Git.