Cloudflare D1
SQLite driver for Cloudflare D1 using Worker bindings
Requirements
- Cloudflare Workers environment (no
nodejs_compatflag needed)
Configuration
import { createClient } from "viborm/d1";
export default {
async fetch(request: Request, env: Env) {
const client = createClient({
database: env.DB, // D1 binding from wrangler.toml
schema,
});
const users = await client.user.findMany();
return Response.json(users);
},
};
Options
| Option | Type | Description |
|---|---|---|
database |
D1Database |
D1 database binding from Worker env |
Binary values
Blob fields bind Uint8Array values directly to D1, and D1’s byte-array
results are normalized back to a plain Uint8Array — no Node Buffer or
nodejs_compat flag involved.
wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Transactions & Batching
D1 does not support traditional dynamic transactions, but VibORM provides full support for batch mode using D1’s native batch() API.
Batch Mode (Recommended)
Use the array API for atomic operations - VibORM uses D1’s native batch() under the hood:
// Atomic execution using D1's native batch()
const [user, post] = await client.$transaction([
client.user.create({ data: { name: "Alice", email: "alice@example.com" } }),
client.post.create({ data: { title: "Hello", authorId: "preset-id" } }),
]);
Dynamic Transactions
Dynamic transactions (callback API) are unsupported and reject:
// Throws TransactionError: D1 does not support callback transactions
await client.$transaction(async (tx) => {
const user = await tx.user.create({ data: { name: "Alice" } });
await tx.post.create({ data: { title: "Hello", authorId: user.id } });
});
Migrations
Schema push executes atomically through D1’s native batch(). File-based
migrate apply requires a callback transaction and rejects on D1 — apply
migrations with wrangler d1 migrations instead.
Capabilities
Dynamic transactions reject; batch mode is fully supported via D1’s native batch(). See the feature matrix for the full comparison.
Limitations
- Batch operations cannot read each other’s results — use a single nested write for dependent mutations
- Only available in Cloudflare Workers
- SQLite dialect - no
LATERALjoins, limitedFULL OUTER JOIN - JSON columns are parsed automatically
- Boolean values stored as integers (0/1)