Files
skills/docs/persistence/database/db-sqlite/src/drivers/bun-driver.md
2026-05-29 08:20:56 +01:00

3.5 KiB

bun-driver

Purpose

Provides createBunDriver, the server-side SQLite driver for @suaveplan/db-sqlite. It dynamically imports bun:sqlite (a built-in Bun module) and returns a thin wrapper holding the raw Database instance plus an idempotent close() function. The isBunEnvironment() guard ensures the driver is never accidentally called in a browser context — doing so raises SQLITE.ENVIRONMENT_ERROR immediately rather than surfacing a confusing module-not-found error at import time.

The dynamic import("bun:sqlite") pattern keeps the module evaluatable in non-Bun environments (so bundlers can tree-shake it out and browser builds do not fail), while still providing full type information from @types/bun.

Features

  • createBunDriver(options?) — opens an in-memory (default) or file-backed SQLite database via bun:sqlite
  • isBunEnvironment() — detects Bun runtime via process.versions.bun
  • BunDriverResult — { sqlite, close } shape; close() is idempotent (safe to call multiple times)
  • Throws SqliteError(SQLITE.ENVIRONMENT_ERROR) when called outside Bun
  • Throws SqliteError(SQLITE.DRIVER_INIT_FAILED) if Database constructor throws (e.g. bad path, locked file)
  • readonly option forwarded to bun:sqlite Database constructor

Usage: Basic Example

import { createBunDriver } from "@suaveplan/db-sqlite/drivers/bun-driver";

const { sqlite, close } = await createBunDriver();
// sqlite is a bun:sqlite Database instance — run raw SQL or pass to Drizzle
await close();

Usage: Advanced Example

import { createBunDriver, isBunEnvironment } from "@suaveplan/db-sqlite/drivers/bun-driver";

if (!isBunEnvironment()) {
  throw new Error("Server-side only path");
}

const { sqlite, close } = await createBunDriver({
  filename: "/data/app.db",
  readonly: false,
});

try {
  sqlite.run("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT)");
  sqlite.run("INSERT OR REPLACE INTO kv VALUES (?, ?)", ["hello", "world"]);
} finally {
  await close(); // second call is a no-op
  await close(); // safe
}

API Reference

isBunEnvironment(): boolean

Returns true when process.versions.bun is defined. Safe to call in any environment.

createBunDriver(options?: BunDriverOptions): Promise<BunDriverResult>

Opens a SQLite database. Throws SqliteError(SQLITE.ENVIRONMENT_ERROR) outside Bun, SqliteError(SQLITE.DRIVER_INIT_FAILED) on open failure.

Parameters

Name Type Default Description
options.filename string ":memory:" File path or ":memory:"
options.readonly boolean false Open in read-only mode

BunDriverResult

interface BunDriverResult {
  sqlite: Database;         // bun:sqlite Database instance
  close: () => Promise<void>; // idempotent — safe to call multiple times
}

Implementation Notes

close() sets a closed flag so repeated calls are no-ops rather than throwing "database already closed". This is intentional: callers cleaning up in finally blocks should not have to track whether they already closed.

The bun:sqlite import is deferred via await import("bun:sqlite") inside the function body so that bundlers processing non-Bun targets (e.g. a Vite browser build) can externalize or ignore the module without causing a build error at parse time. The isBunEnvironment() guard before the import provides an early exit in the rare case this driver is invoked in a test environment that stubs the process object.