Drizzle ORM adapter for Deno's built-in node:sqlite module.
// deno.json
{
"imports": {
"@hotsauce/drizzle-runtime-sqlite": "jsr:@hotsauce/drizzle-runtime-sqlite@^0.1.0",
"drizzle-orm": "npm:drizzle-orm@^0.45.0"
}
}import { drizzle } from "@hotsauce/drizzle-runtime-sqlite";
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
const users = sqliteTable("users", {
id: integer("id").primaryKey(),
name: text("name").notNull(),
});
// In-memory database
const db = drizzle(":memory:", { schema: { users } });
// Or with a file path
const db = drizzle("./data.db", { schema: { users } });
// Standard Drizzle operations
await db.insert(users).values({ name: "Alice" });
const allUsers = await db.select().from(users);If you need more control, use createClient() with drizzle-orm's sqlite-proxy:
import { drizzle } from "drizzle-orm/sqlite-proxy";
import { createClient } from "@hotsauce/drizzle-runtime-sqlite";
const client = createClient(":memory:");
const db = drizzle(client.run, client.batch, { schema: { users } });
// Access the underlying DatabaseSync
client.db.exec("PRAGMA journal_mode = WAL");A drop-in replacement for better-sqlite3 in drizzle-kit's connections is available:
import { createDrizzleKitDriver } from "@hotsauce/drizzle-runtime-sqlite/kit";
const driver = await createDrizzleKitDriver({ url: "./database.db" });
// Returns drizzle-kit compatible interface:
// { query, run, proxy, transactionProxy, migrate, packageName: "node:sqlite" }Note: This driver is intended for integration into drizzle-kit itself and is not currently tested independently. Use at your own risk.
- Deno 2.6.0+ (first version with
stmt.columns()support)- Deno 2.7.0+: Full functionality with
setReturnArrays
- Deno 2.7.0+: Full functionality with
- Node.js 22.16+ or 24.0+ (for full functionality)
- Node 22.5.0-22.15.x: Works, but join queries may return incorrect column ordering due to missing
setReturnArrays
- Node 22.5.0-22.15.x: Works, but join queries may return incorrect column ordering due to missing
Without the setReturnArrays API, this driver falls back to converting object rows to arrays using column metadata. This can produce incorrect results for joins that select columns with duplicate names:
// May return incorrect column ordering on older runtime versions
const result = await db
.select({ userId: users.id, postId: posts.id })
.from(users)
.innerJoin(posts, eq(users.id, posts.userId));Solution: Use Deno 2.7+ or Node.js 22.16+/24+, which support the setReturnArrays API for correct ordering.
| Runtime | stmt.columns() |
setReturnArrays |
Status |
|---|---|---|---|
| Deno < 2.6 | ❌ | ❌ | Not supported |
| Deno 2.6.x | ✅ | ❌ | Works (join limitations) |
| Deno 2.7+ | ✅ | ✅ | Full support |
| Node < 22.5 | ❌ | ❌ | Not supported |
| Node 22.5-22.15 | ✅ | ❌ | Works (join limitations) |
| Node 22.16+/24+ | ✅ | ✅ | Full support |
Both Deno and Node's node:sqlite bundle SQLite without the SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile option. This means the following Drizzle operations will fail:
// ❌ Not supported
await db.delete(users).where(eq(users.active, false)).limit(10);
await db.update(users).set({ status: "archived" }).orderBy(users.createdAt).limit(5);Workaround: Select the IDs first, then delete/update by ID:
// ✅ Supported
const toDelete = await db
.select({ id: users.id })
.from(users)
.where(eq(users.active, false))
.limit(10);
await db.delete(users).where(
inArray(users.id, toDelete.map(r => r.id))
);This is a SQLite compile-time limitation, not a driver bug. If you need this feature, consider using better-sqlite3 with drizzle-orm/better-sqlite3 instead, as it compiles SQLite with this option enabled.
This driver uses Drizzle's sqlite-proxy pattern. While the query builder returns objects as expected:
const users = await db.select().from(usersTable);
// → [{ id: 1, name: 'Alice' }] ✅ ObjectsRaw SQL queries via db.get() and db.all() return arrays instead of objects:
const result = await db.get(sql`SELECT id, name FROM users WHERE id = 1`);
// → [1, 'Alice'] (array, not { id: 1, name: 'Alice' })
const results = await db.all(sql`SELECT id, name FROM users`);
// → [[1, 'Alice'], [2, 'Bob']] (array of arrays)This matches the sqlite-proxy specification. For most use cases, prefer the query builder which returns properly typed objects.
- Deno 2.x (with
--unstable-bundlefor building kit-string) - Docker and Docker Compose
- Make
# Enable pre-commit hooks (runs fmt/lint/check)
git config core.hooksPath .githooks && \
chmod +x .githooks/pre-commitThe ./kit-string export is generated from src/kit.ts and must be built before publishing:
# Generate dist/kit-string.ts (required before deno publish)
deno task build:kit-stringCI runs this automatically before deno publish. For local publishing:
deno task build:kit-string && deno publishTests run in Docker containers to ensure consistent environments.
# Clone Drizzle's shared test suite (required)
make clone-repo
# Run Deno 2.7.2 tests (default)
make test-deno-2.7
# Run Deno 2.6.0 tests (minimum supported)
make test-deno-2.6
# Run Node 22 tests
make test-node22
# Run Node 24 tests
make test-node24All test targets use Drizzle's official shared test suite (~130 tests) to ensure compatibility with the sqlite-proxy pattern.
MIT