Quick Start
Run the maintained effect-auth Cloudflare example and trace its production-shaped integration.
This path runs the example used by release smoke checks: a TanStack Start app Worker proxies same-origin /auth/* requests to a dedicated effect-auth Worker backed by D1 and Durable Object rate limiting. Local auth email goes to a D1 outbox, so no external provider is needed.
| You will verify | Concrete flow |
|---|---|
| Passwordless sign-in | Request a magic link, open it from the local outbox, receive a session cookie |
| Protected application | Open the private documents workspace and create an app-owned resource |
| Account recovery | Complete password reset through the local development outbox |
| Runtime boundaries | App Worker, auth Worker, service binding, D1, rate limiter, and email adapter |
Run locally
You need Git and Bun 1.3 or newer. From a directory where you keep projects:
git clone https://github.com/nr1brolyfan/effect-auth.git
cd effect-auth
bun install
AUTH_EMAIL_FROM=demo@example.com \
AUTH_PUBLIC_URL=http://localhost:3000 \
bun run --filter tanstack-cloudflare-auth-split dev:localThen complete one realistic product flow:
- Open
http://localhost:3000and choose Magic link. - Open
/dev-email-outboxand follow the newest generated link. - Open
/documentsand create a private document. - Sign out and complete a password reset through the local outbox.
Password sign-in intentionally enters the demo login-approval flow. The Google, Discord, and GitHub buttons are placeholders; use magic link for the shortest successful path. The outbox and approval screen are development UX, not production authorization or mail delivery.
Run the same core path automatically with:
AUTH_EMAIL_FROM=demo@example.com \
AUTH_PUBLIC_URL=http://localhost:3000 \
bun run --filter tanstack-cloudflare-auth-split smoke:localThe smoke test covers magic link, password reset, login approval delivery, session persistence, and cleanup.
Trace the request
The split topology keeps app/SSR work in one Worker and secrets, auth storage, and rate limiting in another. The app route forwarding the contract is deliberately small:
export const Route = createFileRoute("/auth/$")({
server: {
handlers: {
GET: ({ request }) => env.AUTH_BACKEND.fetch(request),
POST: ({ request }) => env.AUTH_BACKEND.fetch(request),
},
},
});The browser client stays same-origin and decodes the standard preset contract:
import { createAuthClient } from "@effect-auth/core/Client";
export const authClient = createAuthClient();
const session = await authClient.session.currentOrUndefined();Origin allowlisting protects unsafe auth requests against CSRF; it does not add CORS headers. Prefer same-origin routing unless your deployment requires a separate browser-visible auth origin.
Read the implementation
| Concern | Maintained source |
|---|---|
| Cloudflare resources | alchemy.run.ts |
| Auth Layer graph | src/server/auth.ts |
| Auth Worker entry | src/workers/auth-backend.ts |
| Same-origin route | src/routes/auth/$.ts |
| Typed browser client | src/auth/client.ts |
| Sign-in and session UI | src/routes/index.tsx |
| Protected domain workflow | src/server/documents.ts |
Use the files as a dependency and ownership map, not a blind copy: select only the features your public contract mounts, preserve your framework conventions, and supply every dependency reported by the resulting Layer type.
Adapt it to your application
- Install pinned core, Effect, and adapter packages.
- Select the authentication features and HTTP endpoints your application needs.
- Apply the migration array matching your database before traffic.
- Build runtime Layers for storage, crypto, secrets, mail, rate limiting, and enabled features.
- Bind auth to the framework, create the matching client contract, and handle successful continuation states such as MFA or verification explicitly.
- Verify origin policy, cookies, migrations, email, abuse controls, and recovery using the Production Checklist.
| Local example | Production replacement |
|---|---|
| D1 development database | Managed D1 with backups, retention, migration ledger, and recovery testing |
| D1 email outbox | Cloudflare Send Email or an application-owned AuthMailer implementation |
| Example secret fallback | Unique protected secret material per environment; never commit or log it |
| Demo login approval UI | App-authorized, audited review policy or removal of the feature |
Secure __Host- cookies on localhost | HTTPS with the same secure cookie profile and an exact public origin |
Using a coding agent
Give the agent /llms.txt, require public package subpaths, and have it inspect your runtime, database, user model, and installed versions before proposing changes. It should ask which features you need, choose the integration boundary per endpoint, preserve your architecture, and run your repository checks.