By default, named parameters require a $, :, or @ prefix. With strict: true, you can bind values without prefixes, and missing parameters throw an error:
import { Database } from "bun:sqlite";const db = new Database(":memory:", { strict: true });const query = db.query("SELECT $name;");query.all({ name: "Alice" }); // no $ prefix needed
import { Database } from "bun:sqlite";{ using db = new Database("mydb.sqlite"); using query = db.query("SELECT 'hello' as msg;"); console.log(query.get()); // { msg: "hello" }} // db and query are automatically closed here
db.query() compiles and caches the SQL statement. Calling it again with the same SQL string returns the cached compiled form, not a new compilation.
const query = db.query("SELECT * FROM users WHERE id = $id");query.get({ $id: 1 }); // first row matching id=1query.all({ $id: 2 }); // all rows matching id=2
Caching applies to the compiled prepared statement, not the query results. The same cached statement can be reused safely with different parameter values.
class Movie { title: string; year: number; get isRecent() { return this.year >= 2020; }}const query = db.query("SELECT title, year FROM movies").as(Movie);const movies = query.all();console.log(movies[0].isRecent); // true or false
The class constructor is not called. Columns are assigned directly to the object and the class prototype is attached. Use this for methods and getters, not constructor initialization.
insertMany(cats); // BEGINinsertMany.deferred(cats); // BEGIN DEFERREDinsertMany.immediate(cats); // BEGIN IMMEDIATEinsertMany.exclusive(cats); // BEGIN EXCLUSIVE
WAL mode creates -wal and -shm sidecar files. On macOS (which uses Apple’s SQLite), these persist after db.close(). To clean them up reliably on all platforms:
import { Database, constants } from "bun:sqlite";const db = new Database("mydb.sqlite");db.run("PRAGMA journal_mode = WAL;");// ... use the database ...db.fileControl(constants.SQLITE_FCNTL_PERSIST_WAL, 0);db.run("PRAGMA wal_checkpoint(TRUNCATE);");db.close();// only mydb.sqlite remains
SQLite supports 64-bit signed integers, but JavaScript numbers only safely represent up to 53 bits. By default, bun:sqlite returns integers as number. Enable safeIntegers to use bigint for large values:
import { Database } from "bun:sqlite";const db = new Database(":memory:", { safeIntegers: true });const query = db.query(`SELECT ${BigInt(Number.MAX_SAFE_INTEGER) + 102n} as big_id`);const result = query.get();console.log(result.big_id); // 9007199254741093n (bigint)
With safeIntegers: true, passing a bigint that exceeds 64 bits throws a RangeError.
Serialize and deserialize the entire database to/from a Uint8Array:
const original = new Database("mydb.sqlite");const bytes = original.serialize(); // Uint8Arrayconst copy = Database.deserialize(bytes); // new in-memory DB with same data