| name | bun-sqlite |
| description | Use for bun:sqlite, SQLite operations, prepared statements, transactions, and queries. |
| metadata | {"version":"1.0.0"} |
| license | MIT |
Bun SQLite
Bun has a built-in, high-performance SQLite driver via bun:sqlite.
Quick Start
import { Database } from "bun:sqlite";
const db = new Database("mydb.sqlite");
db.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE
)
`);
db.run("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"]);
const users = db.query("SELECT * FROM users").all();
console.log(users);
db.close();
Opening Databases
import { Database } from "bun:sqlite";
const db = new Database("data.sqlite");
const memDb = new Database(":memory:");
const readDb = new Database("data.sqlite", { readonly: true });
const createDb = new Database("new.sqlite", { create: true });
const strictDb = new Database("strict.sqlite", { strict: true });
Running Queries
Direct Execution
db.run("CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT)");
db.run("INSERT INTO items (name) VALUES (?)", ["Item 1"]);
db.run("DELETE FROM items WHERE id = ?", [1]);
const result = db.run("DELETE FROM items WHERE id > ?", [10]);
console.log(result.changes);
console.log(result.lastInsertRowid);
Prepared Statements (Recommended)
const stmt = db.prepare("SELECT * FROM users WHERE id = ?");
const user = stmt.get(1);
const allUsers = db.prepare("SELECT * FROM users").all();
const values = db.prepare("SELECT name, email FROM users").values();
const iter = db.prepare("SELECT * FROM users");
for (const user of iter.iterate()) {
console.log(user);
}
Parameters
Positional Parameters
const stmt = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
stmt.run("Bob", "bob@example.com");
stmt.run(["Charlie", "charlie@example.com"]);
Named Parameters
const stmt = db.prepare("INSERT INTO users (name, email) VALUES ($name, $email)");
stmt.run({ $name: "Dave", $email: "dave@example.com" });
const stmt2 = db.prepare("SELECT * FROM users WHERE name = :name");
stmt2.get({ name: "Dave" });
Query Methods
const stmt = db.prepare("SELECT * FROM users WHERE active = ?");
const first = stmt.get(true);
const all = stmt.all(true);
const values = stmt.values(true);
for (const row of stmt.iterate(true)) {
processRow(row);
}
db.prepare("DELETE FROM cache WHERE expires < ?").run(Date.now());
Transactions
const insertMany = db.transaction((users: { name: string; email: string }[]) => {
const insert = db.prepare("INSERT INTO users (name, email) VALUES ($name, $email)");
for (const user of users) {
insert.run(user);
}
return users.length;
});
const count = insertMany([
{ name: "User1", email: "user1@example.com" },
{ name: "User2", email: "user2@example.com" },
]);
const tx = db.transaction(() => {
db.run("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"]);
db.run("UPDATE accounts SET balance = balance - 100 WHERE user_id = ?", [1]);
});
tx.deferred();
tx.immediate();
tx.exclusive();
Batch Operations
db.run("PRAGMA journal_mode = WAL");
const insertBulk = db.transaction((items: string[]) => {
const stmt = db.prepare("INSERT INTO items (name) VALUES (?)");
for (const item of items) {
stmt.run(item);
}
});
insertBulk(["A", "B", "C", "D", "E"]);
Column Types
const bigStmt = db.prepare("SELECT COUNT(*) as count FROM users");
const result = bigStmt.get();
db.run("INSERT INTO files (data) VALUES (?)", [new Uint8Array([1, 2, 3])]);
const file = db.prepare("SELECT data FROM files WHERE id = ?").get(1);
Column Definitions
const stmt = db.prepare("SELECT * FROM users");
const columns = stmt.columnNames;
const typedStmt = db.prepare<{ id: number; name: string }, [number]>(
"SELECT id, name FROM users WHERE id = ?",
);
const user = typedStmt.get(1);
Error Handling
import { Database, SQLiteError } from "bun:sqlite";
try {
db.run("INSERT INTO users (email) VALUES (?)", ["duplicate@example.com"]);
} catch (error) {
if (error instanceof SQLiteError) {
console.error("SQLite error:", error.code, error.message);
}
throw error;
}
Database Management
db.close();
console.log(db.inTransaction);
const buffer = db.serialize();
await Bun.write("backup.sqlite", buffer);
const data = await Bun.file("backup.sqlite").arrayBuffer();
const restored = Database.deserialize(data);
console.log(db.filename);
Common Patterns
Repository Pattern
import { Database } from "bun:sqlite";
interface User {
id: number;
name: string;
email: string;
}
class UserRepository {
private db: Database;
private stmts: {
findById: ReturnType<Database["prepare"]>;
findAll: ReturnType<Database["prepare"]>;
create: ReturnType<Database["prepare"]>;
update: ReturnType<Database["prepare"]>;
delete: ReturnType<Database["prepare"]>;
};
constructor(db: Database) {
this.db = db;
this.stmts = {
findById: db.prepare("SELECT * FROM users WHERE id = ?"),
findAll: db.prepare("SELECT * FROM users"),
create: db.prepare("INSERT INTO users (name, email) VALUES ($name, $email)"),
update: db.prepare("UPDATE users SET name = $name, email = $email WHERE id = $id"),
delete: db.prepare("DELETE FROM users WHERE id = ?"),
};
}
findById(id: number): User | null {
return this.stmts.findById.get(id) as User | null;
}
findAll(): User[] {
return this.stmts.findAll.all() as User[];
}
create(user: Omit<User, "id">): number {
const result = this.stmts.create.run(user);
return Number(result.lastInsertRowid);
}
}
Common Errors
| Error | Cause | Fix |
|---|
SQLITE_CONSTRAINT | Constraint violation | Check UNIQUE/FK constraints |
SQLITE_BUSY | Database locked | Use WAL mode, add retry logic |
no such table | Table doesn't exist | Run CREATE TABLE first |
database is locked | Concurrent access | Enable WAL mode |
Performance Tips
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = 10000;
PRAGMA foreign_keys = ON;
When to Load References
Load references/pragmas.md when:
- Performance tuning
- Journal modes
- Memory configuration
Load references/fts.md when:
- Full-text search
- FTS5 configuration