CloudflareD1
Source:
packages/better-auth/src/CloudflareD1.tsKind: Layer · Provides:BetterAuth.Database
Cloudflare D1 database layer for Better Auth.
At runtime the Worker reaches the database through its native D1 binding
(the layer bakes in QueryDatabaseBinding). At deploy time, schema
migrations run over the D1 HTTP query API — which also transparently
targets the local D1 simulator under alchemy dev.
Using D1 as the auth database
Section titled “Using D1 as the auth database”Provide the layer on the Worker impl effect that yields BetterAuth.
The database resource can be referenced from module scope — the layer
accepts the resource or its Effect.
import { BetterAuth } from "@alchemy.run/better-auth";import { CloudflareD1 } from "@alchemy.run/better-auth/CloudflareD1";import * as Cloudflare from "alchemy/Cloudflare";
export const AuthDb = Cloudflare.D1.Database("AuthDb");
export default class Api extends Cloudflare.Worker<Api>()( "Api", { main: import.meta.url, compatibility: { flags: ["nodejs_compat"] } }, Effect.gen(function* () { const auth = yield* BetterAuth({ basePath: "/auth", emailAndPassword: { enabled: true }, }); return { fetch: Effect.gen(function* () { const request = yield* HttpServerRequest; if (request.url.startsWith("/auth")) { return yield* auth.fetch; } const session = yield* auth.getSession(); return yield* HttpServerResponse.json({ user: session?.user ?? null }); }), }; }).pipe(Effect.provide(CloudflareD1(AuthDb))),) {}Migrations
Section titled “Migrations”The schema migration Action connects over the D1 HTTP API at deploy time — the Worker’s native binding is never used outside the deployed runtime, and no migration code ships in the Worker bundle.
const auth = yield* BetterAuth({ migrate: false, // manage the schema yourself emailAndPassword: { enabled: true },});