JavaScript API Index

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.

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

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 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:

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.


  1. ^ If your web server cannot serve the text/javascript mimetype for .mjs files, you may need to rename the file to sqlite3.js