Allow creating a new database
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
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
}
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
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
.
Data to load
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
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
This is an alias of new Database()
See Database
staticsetCustomSQLite(path: string): boolean
Change the dynamic library path to SQLite
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
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.
Open or create a SQLite3 database
The filename of the database to open. Pass an empty string (""
) or ":memory:"
or undefined for an in-memory database.
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
[Symbol.dispose](): void
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.
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.
name/path of the extension to load
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
.
The SQL query to compile
Optional bindings for the query
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
.
The SQL query to compile
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 type | SQLite type |
---|---|
string | TEXT |
number | INTEGER or DECIMAL |
boolean | INTEGER (1 or 0) |
Uint8Array | BLOB |
Buffer | BLOB |
bigint | INTEGER |
null | NULL |
The SQL query to run
Optional bindings for the query
Database
instance
serialize(name?: string): Buffer
Save the database to an in-memory Buffer object.
Internally, this calls sqlite3_serialize
.
Name to save the database as
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"
}
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).
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
The value to check
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.iterator](): IterableIterator<ReturnType>
all(params: ParamsType): ReturnType[]
Execute the prepared statement and return all results as objects.
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
.
A class to use
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
.
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
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
.
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.
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
.