Use Cloudflare D1 with DaloyJS Cloudflare D1 is a serverless SQLite-compatible database built into Cloudflare Workers. You access it through a Worker binding (no network driver, no auth token, no TCP), making it the lowest-friction database for the Cloudflare adapter .
1. Provision via Wrangler pnpm add - D wrangler
pnpm dlx wrangler d1 create my - app - db Add the returned binding to your wrangler.toml:
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "<id-from-create>" 2. Type the binding // src/types/env.d.ts
export interface Env {
DB : D1Database ;
} 3. Decorate the app per-request D1 bindings live on env, not process.env, so decorate inside the Worker's fetch handler and call app.fetch(req) directly:
Per-request binding flow01 Worker fetch(req, env) env.DB is the D1 binding
02 app.decorate('db', env.DB) attach the binding to app state
03 app.fetch(req) route handler reads state.db
04 state.db.prepare(...).all() query D1, no network driver
D1 bindings live on env, not process.env, so decorate the app inside the Worker fetch handler on every request before calling app.fetch(req). import { z } from "zod" ;
import { App, secureHeaders } from "@daloyjs/core" ;
import type { Env } from "./types/env" ;
const app = new App ();
app. use ( secureHeaders ());
const TodoSchema = z. object ({ id: z. number (), title: z. string (), done: z. boolean () });
app. route ({
method: "GET" ,
path: "/todos" ,
operationId: "listTodos" ,
responses: { 200 : { description: "ok" , body: z. array (TodoSchema) } },
handler : async ({ state }) => {
const { results } = await state.db
. prepare ( "select id, title, done from todos" )
. all <{ id : number ; title : string ; done : number }>();
return {
status: 200 ,
body: results. map (( r ) => ({ ... r, done: Boolean (r.done) })),
};
},
});
export default {
async fetch (req : Request, env : Env) {
app. decorate ( "db" , env. DB );
return app. fetch (req);
} ,
} ; 4. Augment app state // src/types/state.d.ts
declare module "@daloyjs/core" {
interface AppState {
db : D1Database ;
}
} Migrations pnpm dlx wrangler d1 migrations create my - app - db init
pnpm dlx wrangler d1 migrations apply my - app - db -- local
pnpm dlx wrangler d1 migrations apply my - app - db -- remote With Drizzle ORM pnpm add drizzle - orm
// src/db/drizzle.ts
import { drizzle } from "drizzle-orm/d1" ;
import type { Env } from "../types/env" ;
export const createDb = ( env : Env ) => drizzle (env. DB ); With Prisma Prisma supports D1 via the D1 Driver Adapter . Construct the adapter inside the Worker handler since it needs the runtime binding.
Limitations to know D1 only runs in Cloudflare Workers, no Node.js, Lambda, or Edge runtime support. Local development uses wrangler dev with a local SQLite file; behavior is close but not identical to production. For multi-runtime portability, prefer Turso (libSQL) instead. See also Turso , Neon , and the database hosting overview .