API docs for the JS APIs are embedded in their JS files. The docs in these pages are largely expanded and reformatted versions of those docs.
- The C-style API is essentially a mirror of
most of the canonical C API and comes in
two flavors:
- A 1-to-1 export of the WASM-generated bindings, with no
automatic argument or result type conversions. This level is
exposed via the
sqlite3.wasm.exports
object and is generally not needed in client code. This is as close to the native API as JS can get, but can be very cumbersome to use from client code due to differing data type support between JS and WASM. - A wrapper around that, exposed via the
sqlite3.capi
namespace, which provides basic type-conversion for most arguments and result values. It has a relative handful of differences with the native C API to account for discrepancies between the JS and C worlds, as well as some "convenience extensions" which apply only when certain functions are called in ways not directly supported by the C APIs. This API is primarily intended for use as the basis for implementing higher-level, more user-friendly APIs, but many of its routines are useful at arbitrary levels of client code.
- A 1-to-1 export of the WASM-generated bindings, with no
automatic argument or result type conversions. This level is
exposed via the
- High-level object-oriented APIs:
- OO API #1 is a high-level OO API which should feel familiar to those who have used high-level database API bindings in JavaScript. It is not specifically modelled after any such API but was modelled based on prior experience with, and prior art pertaining to, binding sqlite3 to various scripting engines.
- Worker API #1 and its Promise-style proxy both run sqlite3 in a separate thread from the client application. Because this makes direct access to a db handle impossible, this approach severely limits the features available to the client but may be ideal for certain use cases.
- Special-case APIs:
- Numerous WASM-specific utilities help glue the JS and C parts of other APIs.
- C structs in JS
- Virtual Tables in JS
- sqlite3_vfs in JS
Before using one of those APIs, however, it is necessary to load and initialize the library, which is covered in section 2 of this document.
API Stability
- The C-style API is a close mirror of the sqlite3 C API and has the same strong interface stability guarantees, with the minor exception that JS-side bindings of those APIs may be extended in ways which do not affect their backwards compatibility but improve their JS-side usability, such as the addition of new argument type conversions.
- The JS-specific APIs as a whole are, as of late 2022, still very much beta and subject to change.
See also: client-breaking API changes
Loading and Initializing the API
The sqlite3 JS API is comprised of numerous files, many of which get
bundled together by build-time automation, assembled
into a form usable by WASM-capable browsers. Such a build is
typically a pair of files named sqlite3.js
and sqlite3.wasm
, but
several standalone files named sqlite3-<something>.js
are required
for specific use cases. sqlite3.js
contains not only the main APIs,
but also the "glue" necessary for loading the WASM file and getting it
plugged in to the environment.
Only a JS thread which loads sqlite3.js
(or equivalent) can make
direct use of the API. Each thread which loads it has its own
independent instance of the WASM runtime, sharing no state between
them. Thus sqlite3.js
is typically loaded only a single time from
whichever thread the application chooses. Because of that, and because
each JS runtime instance is single-threaded, multi-threaded use of a
single database handle is not possible in the JS environment.
Similarly, because each WASM runtime instance has its own virtual
(emulated) filesystem, the same database name in any two WASM
instances will refer to different database instances. The exception is
if a database is stored in persistent storage, but
concurrent access to a single database may be prohibited by the
filesystem driver.
In client code, the loading and initialization typically looks like one of the following...
Main-thread and Worker-thread Installation
To load the complete sqlite3 API into the same thread as client-side code, do one of the following:
For main-thread use, load it from HTML:
<script src="sqlite3.js"></script>
Or from a client-level Worker:
importScripts("sqlite3.js");
Be sure to read this gotcha if sqlite3.js
is in
a directory other than the one the client application is in.
For both approaches, load the WASM file and activate the API with:
self.sqlite3InitModule().then((sqlite3)=>{
... do something with sqlite3 ...
});
sqlite3InitModule()
is a function installed by Emscripten to load
and initialize the module. It accepts an optional object to act as the
so-called Emscripten Module, with which the client may be notified of
loading progress an errors. See the Emscripten docs on the
topic for full
details. Note that this project has no influence over those options
and the Emscripten project may change them at any time, so we neither
document nor support them. Note, also, that this project may attempt
to internally override any specific option, potentially leading to
undesired side effects if client code does the same.
See also:
Dedicated Worker mode, noting that that approach severely limits what the client may do with the API.
Dedicated sqlite3 Worker Installation ("Worker1"):
If sqlite3 should operate entirely in its own Worker thread, separate from all client-level code, the the Worker1 API and its Promise-style proxy provide such a feature out of the box.
Loading from an ES6 Module
The canonical build of sqlite3.js
includes sqlite3.mjs
, with mjs
being the preferred file extension for ES6 modules1. The module
exports only a single symbol: a function which loads the associated
WASM file and initializes the library (the same function demonstrated
for main-thread use above). It can be loaded from an ES6 module with
something like:
import {default as sqlite3InitModule} from "./jswasm/sqlite3.mjs";
sqlite3InitModule().then((sqlite3)=>{
console.log("Loaded sqlite3",sqlite3.version);
});
With the caveat that, as of late 2022, not all browsers support loading ES6 modules from Workers (e.g. Firefox).
Or from an HTML script tag like:
<script type="module">
// same code as above
</script>
Using "Bundler" Tools
Separate files are provided in the release zipfile for use with
JavaScript "bundler" tools commonly seen in node.js-based build
environments, while also admitting that we do not use such tools so
release these builds as-is with no guarantees that they'll work with
any given bundler. In such environments,
jswasm/*-bundler-friendly.*js
should be used in place of like-named
files without the bundler-friendly
suffix.
Specifically:
sqlite3-bundler-friendly.mjs
should be used in place ofsqlite3.js
orsqlite3.mjs
sqlite3-worker1-bundler-friendly.mjs
should be used in place ofsqlite3-worker1.js
(This file has a.js
extension, and is not an EM6 module, in the 3.41 release.)It is not clear whether the Promiser API can work with bundlers because doing so apparenly requires loading a module-type Worker, a feature neither Firefox nor Safari support as of March 2023.sqlite3-worker1-promiser-bundler-friendly.js
should be used in place ofsqlite3-worker1-promiser.js
Some files do not have this variant, in which case they may be used
as-is with bundlers (e.g. sqlite3-opfs-async-proxy.js
).
The sqlite3 Namespace
When the sqlite3 module is initialized it creates a so-called namespace object which contains its various APIs. In JS notation it looks like:
{
/* The namespace for the C-style APIs. */
capi: {...},
/* WASM-specific utilities, abstracted to be independent of,
and configurable for use with, arbitrary WASM runtime
environments. */
wasm: {...},
/* Exception class used primarily by the oo1 API. */
SQLite3Error: ...,
/* Exception class for reporting WASM-side allocation errors. */
WasmAllocError: ...,
/* The OO API #1. */
oo1: {...},
/* Utility code for creating virtual table implementations. */
vtab: {...},
/* Utility code for creating sqlite3_vfs's. */
vfs: {...},
/* The options with which the API was configured. Whether or not
modifying them after the bootstrapping process will have any
useful effect is unspecified and may change with any given
version. Clients must not rely on that capability. */
config: {...},
/* The library reserves this property for client-side use and
promises to never define a property with this name nor to
ever rely on specific contents of it. It makes no such
guarantees for other properties. */
client: undefined
}
Any members of that object not listed above are not part of the public API and are subject to change or removal at any time.
Though the namespace object is technically unnamed, and is not
installed into any scope by the included APIs, client-level code
conventionally assigns it the name sqlite3
, and these docs assume it
uses that name. Whether that symbol is kept scope-local or made global
is up to the client.
- ^
If your
web server cannot serve the
text/javascript
mimetype for.mjs
files, you may need to rename the file tosqlite3.js