Use with Drizzle
Last updated 29 October 2026
Use Drizzle ORM on a Tonbo database once the Drizzle quickstart runs: the driver, migrations in the app, synced(), transactions, and what does not work.
The driver
open() returns a DatabaseSync, which Drizzle’s node:sqlite driver takes as its client. The driver ships only in Drizzle’s 1.0 release candidate, so pin it exactly; Tonbo’s Streams acceptance test runs drizzle-orm 1.0.0-rc.5.
Migrations run in the app
drizzle-kit generate reads only the schema, so it runs anywhere. The migrator then runs in the app, on the connection open() returned: it applies the migrations it has not applied, in one transaction, and records each in __drizzle_migrations. The migration replicates like any commit, so every later open, on any host, finds it applied.
Why not drizzle-kit migrate
drizzle-kit migrate, push, pull and studio open the database file with their own driver. The files in the cache root are not SQLite files outside the extension, so they fail with SQLITE_NOTADB and change nothing. Even a file they could open would be a local copy whose changes never reach Tonbo.
synced()
Drizzle knows nothing of synced(). A Drizzle write returns once it is committed on this host. Call await client.synced() on the connection before anything outside the process acts on what you wrote, such as a response. See When a commit is durable.
Transactions
The node:sqlite driver’s transactions are synchronous. Pass a function that is not async, and run each query in it with .run(), .all() or .get() instead of await:
db.transaction((tx) => {
tx.insert(todos).values({ title: "first", done: false }).run();
tx.update(todos).set({ done: true }).where(eq(todos.id, 1)).run();
return tx.select().from(todos).all();
});The transaction commits when the function returns, and rolls back when it throws. An await inside it would let the transaction commit before the awaited query runs; Drizzle’s types reject an async function here. To roll back on purpose, call tx.rollback(), which throws TransactionRollbackError:
import { TransactionRollbackError } from "drizzle-orm";
try {
db.transaction((tx) => {
tx.insert(todos).values({ title: "draft", done: false }).run();
tx.rollback();
});
} catch (error) {
if (!(error instanceof TransactionRollbackError)) throw error;
}What does not work
drizzle-kit migrate,push,pullandstudioagainst the cache root, as above.- Drizzle’s stable releases (0.x) have no node:sqlite driver. Use the release candidate.
asynctransaction functions, and theconcurrenttransaction behavior, which the driver refuses.