bun:sqlite

Bun

Module

bun:sqlite

The 'bun:sqlite' module is a high-performance SQLite3 driver built directly into Bun. The API is simple, synchronous, and inspired by better-sqlite3, offering a clean and intuitive interface for database operations.

Key features include prepared statements, transactions, both named and positional parameters, datatype conversions (BLOB to Uint8Array), mapping query results to classes, and support for bigint. Multi-query statements can be executed in a single call to database.run().

Performance benchmarks show bun:sqlite is approximately 3-6x faster than better-sqlite3 and 8-9x faster than deno.land/x/sqlite for read queries, making it the fastest SQLite driver available for JavaScript.

Vconstants:
{

SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: number

SQLITE_FCNTL_BUSYHANDLER: number

SQLITE_FCNTL_CHUNK_SIZE: number

SQLITE_FCNTL_CKPT_DONE: number

SQLITE_FCNTL_CKPT_START: number

SQLITE_FCNTL_CKSM_FILE: number

SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: number

SQLITE_FCNTL_COMMIT_PHASETWO: number

SQLITE_FCNTL_DATA_VERSION: number

SQLITE_FCNTL_EXTERNAL_READER: number

SQLITE_FCNTL_FILE_POINTER: number

SQLITE_FCNTL_GET_LOCKPROXYFILE: number

SQLITE_FCNTL_HAS_MOVED: number

SQLITE_FCNTL_JOURNAL_POINTER: number

SQLITE_FCNTL_LAST_ERRNO: number

SQLITE_FCNTL_LOCK_TIMEOUT: number

SQLITE_FCNTL_LOCKSTATE: number

SQLITE_FCNTL_MMAP_SIZE: number

SQLITE_FCNTL_OVERWRITE: number

SQLITE_FCNTL_PDB: number

SQLITE_FCNTL_PERSIST_WAL: number

SQLITE_FCNTL_POWERSAFE_OVERWRITE: number

SQLITE_FCNTL_PRAGMA: number

SQLITE_FCNTL_RBU: number

SQLITE_FCNTL_RESERVE_BYTES: number

SQLITE_FCNTL_RESET_CACHE: number

SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: number

SQLITE_FCNTL_SET_LOCKPROXYFILE: number

SQLITE_FCNTL_SIZE_HINT: number

SQLITE_FCNTL_SIZE_LIMIT: number

SQLITE_FCNTL_SYNC: number

SQLITE_FCNTL_SYNC_OMITTED: number

SQLITE_FCNTL_TEMPFILENAME: number

SQLITE_FCNTL_TRACE: number

SQLITE_FCNTL_VFS_POINTER: number

SQLITE_FCNTL_VFSNAME: number

SQLITE_FCNTL_WAL_BLOCK: number

SQLITE_FCNTL_WIN32_AV_RETRY: number

SQLITE_FCNTL_WIN32_GET_HANDLE: number

SQLITE_FCNTL_WIN32_SET_HANDLE: number

SQLITE_FCNTL_ZIPVFS: number

SQLITE_OPEN_AUTOPROXY: number

SQLITE_OPEN_CREATE: number

Allow creating a new database

SQLITE_OPEN_DELETEONCLOSE: number

SQLITE_OPEN_EXCLUSIVE: number

SQLITE_OPEN_EXRESCODE: number

SQLITE_OPEN_FULLMUTEX: number

SQLITE_OPEN_MAIN_DB: number

SQLITE_OPEN_MAIN_JOURNAL: number

SQLITE_OPEN_MEMORY: number

SQLITE_OPEN_NOFOLLOW: number

SQLITE_OPEN_NOMUTEX: number

SQLITE_OPEN_PRIVATECACHE: number

SQLITE_OPEN_READONLY: number

Open the database as read-only (no write operations, no create).

SQLITE_OPEN_READWRITE: number

Open the database for reading and writing

SQLITE_OPEN_SHAREDCACHE: number

SQLITE_OPEN_SUBJOURNAL: number

SQLITE_OPEN_SUPER_JOURNAL: number

SQLITE_OPEN_TEMP_DB: number

SQLITE_OPEN_TEMP_JOURNAL: number

SQLITE_OPEN_TRANSIENT_DB: number

SQLITE_OPEN_URI: number

SQLITE_OPEN_WAL: number

SQLITE_PREPARE_NO_VTAB: number

SQLITE_PREPARE_NORMALIZE: number

SQLITE_PREPARE_PERSISTENT: number

}

Constants from sqlite3.h

This list isn't exhaustive, but some of the ones which are relevant

classDatabaseimplementsDisposable

A SQLite3 database

staticdeserialize(serialized: ArrayBufferLike | TypedArray<ArrayBufferLike>, isReadOnly?: boolean): Database

Load a serialized SQLite3 database

Internally, this calls sqlite3_deserialize.

serialized

Data to load

returns

Database instance

staticopen(filename: string, options?: number |
{

create: boolean

Allow creating a new database

Equivalent to constants.SQLITE_OPEN_CREATE

readonly: boolean

Open the database as read-only (no write operations, no create).

Equivalent to constants.SQLITE_OPEN_READONLY

readwrite: boolean

Open the database as read-write

Equivalent to constants.SQLITE_OPEN_READWRITE

}
): Database

This is an alias of new Database()

See Database

staticsetCustomSQLite(path: string): boolean

Change the dynamic library path to SQLite

path

The path to the SQLite library

constructor(filename?: string, options?: number |
{

create: boolean

Allow creating a new database

Equivalent to constants.SQLITE_OPEN_CREATE

readonly: boolean

Open the database as read-only (no write operations, no create).

Equivalent to constants.SQLITE_OPEN_READONLY

readwrite: boolean

Open the database as read-write

Equivalent to constants.SQLITE_OPEN_READWRITE

safeIntegers: boolean

When set to true, integers are returned as bigint types.

When set to false, integers are returned as number types and truncated to 52 bits.

strict: boolean

When set to false or undefined:

  • Queries missing bound parameters will NOT throw an error
  • Bound named parameters in JavaScript need to exactly match the SQL query.
}
): Database

Open or create a SQLite3 database

filename

The filename of the database to open. Pass an empty string ("") or ":memory:" or undefined for an in-memory database.

options

defaults to {readwrite: true, create: true}. If a number, then it's treated as SQLITE_OPEN_* constant flags.

filename: string

The filename passed when new Database() was called

handle: number

The underlying sqlite3 database handle

In native code, this is not a file descriptor, but an index into an array of database handles

getinTransaction: boolean

close(throwOnError?: boolean): void

Close the database connection.

It is safe to call this method multiple times. If the database is already closed, this is a no-op. Running queries after the database has been closed will throw an error.

throwOnError

If true, then the database will throw an error if it is in use

exec<ParamsType extends SQLQueryBindings[]>(sql: string, bindings: ParamsType[]): Changes

This is an alias of Database.run

fileControl(op: number, arg?: number | ArrayBufferView<ArrayBufferLike>): number

See sqlite3_file_control for more information.

loadExtension(extension: string, entryPoint?: string): void

Load a SQLite3 extension

macOS requires a custom SQLite3 library to be linked because the Apple build of SQLite for macOS disables loading extensions. See Database.setCustomSQLite

Bun chooses the Apple build of SQLite on macOS because it brings a ~50% performance improvement.

extension

name/path of the extension to load

entryPoint

optional entry point of the extension

prepare<ReturnType, ParamsType extends SQLQueryBindings | SQLQueryBindings[]>(sql: string, params?: ParamsType): Statement<ReturnType, ParamsType extends any[] ? ParamsType<ParamsType> : [ParamsType]>

Compile a SQL query and return a Statement object.

This does not cache the compiled query and does not execute the query.

Under the hood, this calls sqlite3_prepare_v3.

sql

The SQL query to compile

params

Optional bindings for the query

returns

A Statement instance

query<ReturnType, ParamsType extends SQLQueryBindings | SQLQueryBindings[]>(sql: string): Statement<ReturnType, ParamsType extends any[] ? ParamsType<ParamsType> : [ParamsType]>

Compile a SQL query and return a Statement object. This is the same as prepare except that it caches the compiled query.

This does not execute the query, but instead prepares it for later execution and caches the compiled query if possible.

Under the hood, this calls sqlite3_prepare_v3.

sql

The SQL query to compile

returns

Statment instance

run<ParamsType extends SQLQueryBindings[]>(sql: string, bindings: ParamsType[]): Changes

Execute a SQL query without returning any results.

This does not cache the query, so if you want to run a query multiple times, you should use prepare instead.

Under the hood, this calls sqlite3_prepare_v3 followed by sqlite3_step and sqlite3_finalize.

The following types can be used when binding parameters:

JavaScript typeSQLite type
stringTEXT
numberINTEGER or DECIMAL
booleanINTEGER (1 or 0)
Uint8ArrayBLOB
BufferBLOB
bigintINTEGER
nullNULL
sql

The SQL query to run

bindings

Optional bindings for the query

returns

Database instance

serialize(name?: string): Buffer

Save the database to an in-memory Buffer object.

Internally, this calls sqlite3_serialize.

name

Name to save the database as

returns

Buffer containing the serialized database

transaction(insideTransaction: (args: any) => void): CallableFunction &
{

deferred: (args: any) => void

uses "BEGIN DEFERRED"

exclusive: (args: any) => void

uses "BEGIN EXCLUSIVE"

immediate: (args: any) => void

uses "BEGIN IMMEDIATE"

}

Creates a function that always runs inside a transaction. When the function is invoked, it will begin a new transaction. When the function returns, the transaction will be committed. If an exception is thrown, the transaction will be rolled back (and the exception will propagate as usual).

insideTransaction

The callback which runs inside a transaction

Vnative: any

The native module implementing the sqlite3 C bindings

It is lazily-initialized, so this will return undefined until the first call to new Database().

The native module makes no gurantees about ABI stability, so it is left untyped

If you need to use it directly for some reason, please let us know because that probably points to a deficiency in this API.

classSQLiteErrorextendsError

Errors from SQLite have a name SQLiteError.

staticprepareStackTrace: (err: Error, stackTraces: CallSite[]) => any

Optional override for formatting stack traces

staticstackTraceLimit: number

The maximum number of stack frames to capture.

staticcaptureStackTrace(targetObject: object, constructorOpt?: Function): void

Create .stack property on a target object

staticisError(value: unknown): asserts value is Error

Check if a value is an instance of Error

value

The value to check

returns

True if the value is an instance of Error, false otherwise

constructor(message?: string): SQLiteError

byteOffset: number

The UTF-8 byte offset of the sqlite3 query that failed, if known

This corresponds to sqlite3_error_offset.

cause: unknown

The cause of the error.

code: string

The name of the SQLite3 error code

errno: number

The SQLite3 extended error code

This corresponds to sqlite3_extended_errcode.

message: string

name: 'SQLiteError'

stack: string

classStatement<ReturnType=unknown, ParamsType extends SQLQueryBindings[]=any[]>implementsDisposable

A prepared statement.

This is returned by Database.prepare and Database.query.

constructor<ReturnType=unknown, ParamsType extends SQLQueryBindings[]=any[]>(nativeHandle: any): Statement<ReturnType, ParamsType>

Creates a new prepared statement from native code.

This is used internally by the Database class. Probably you don't need to call this yourself.

columnNames: string[]

The names of the columns returned by the prepared statement.

native: any

Native object representing the underlying sqlite3_stmt

This is left untyped because the ABI of the native bindings may change at any time.

paramsCount: number

The number of parameters expected in the prepared statement.

[Symbol.dispose](): void

Calls finalize if it wasn't already called.

[Symbol.iterator](): IterableIterator<ReturnType>

all(params: ParamsType): ReturnType[]

Execute the prepared statement and return all results as objects.

params

optional values to bind to the statement. If omitted, the statement is run with the last bound values or no parameters if there are none.

as<T=unknown>(Class: new (args: any[]) => T): Statement<T, ParamsType>

Make get and all return an instance of the provided Class instead of the default Object.

Class

A class to use

returns

The same statement instance, modified to return an instance of Class

This lets you attach methods, getters, and setters to the returned objects.

For performance reasons, constructors for classes are not called, which means initializers will not be called and private fields will not be accessible.

finalize(): void

Finalize the prepared statement, freeing the resources used by the statement and preventing it from being executed again.

This is called automatically when the prepared statement is garbage collected.

It is safe to call this multiple times. Calling this on a finalized statement has no effect.

Internally, this calls sqlite3_finalize.

get(params: ParamsType): null | ReturnType

Execute the prepared statement and return the first result.

If no result is returned, this returns null.

params

optional values to bind to the statement. If omitted, the statement is run with the last bound values or no parameters if there are none.

iterate(params: ParamsType): IterableIterator<ReturnType>

Execute the prepared statement and return an

params

optional values to bind to the statement. If omitted, the statement is run with the last bound values or no parameters if there are none.

run(params: ParamsType): Changes

Execute the prepared statement. This returns undefined.

params

optional values to bind to the statement. If omitted, the statement is run with the last bound values or no parameters if there are none.

toString(): string

Return the expanded SQL string for the prepared statement.

Internally, this calls sqlite3_expanded_sql() on the underlying sqlite3_stmt.

values(params: ParamsType): string | number | bigint | boolean | Uint8Array<ArrayBufferLike>[][]

Execute the prepared statement and return the results as an array of arrays.

In Bun v0.6.7 and earlier, this method returned null if there were no results instead of []. This was changed in v0.6.8 to align more with what people expect.

params

optional values to bind to the statement. If omitted, the statement is run with the last bound values or no parameters if there are none.

Type Definitions

interfaceChanges

An object representing the changes made to the database since the last run or exec call.

changes: number

The number of rows changed by the last run or exec call.

lastInsertRowid: number | bigint

If safeIntegers is true, this is a bigint. Otherwise, it is a number.

typeSQLQueryBindings=string | bigint | NodeJS.TypedArray | number | boolean | null | Record<string, string | bigint | NodeJS.TypedArray | number | boolean | null>