Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 52 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ SQLite Wasm conveniently wrapped as an ES Module.
npm install @sqlite.org/sqlite-wasm
```

```bash
yarn add @sqlite.org/sqlite-wasm
```

```bash
pnpm add @sqlite.org/sqlite-wasm
```

```bash
bun add @sqlite.org/sqlite-wasm
```

## Bug reports

> [!Warning]
Expand All @@ -26,88 +38,20 @@ npm install @sqlite.org/sqlite-wasm

## Usage

There are two ways to use SQLite Wasm:
See the implementation docs for the package entry point that matches your runtime and storage needs:

- [in a worker](#in-a-worker-with-opfs-if-available)
- [in the main thread](#in-the-main-thread-without-opfs)
- [Main-thread browser usage](docs/main-thread.md)
- [Worker usage with OPFS](docs/worker.md)
- [Node.js usage](docs/node.md)
- [Bundler core omit-api build](docs/bundler-core.md)
- [Bundler vtab omit-api build](docs/bundler-vtab.md)
- [Bundler kvvfs omit-api build](docs/bundler-kvvfs.md)
- [Bundler OPFS omit-api build](docs/bundler-opfs.md)
- [Bundler OPFS WebLocks omit-api build](docs/bundler-opfs-wl.md)
- [Bundler OPFS SAH Pool omit-api build](docs/bundler-sah-pool.md)

Only the worker versions allow you to use the origin private file system (OPFS) storage back-end.

### In a worker (with OPFS if available):

> [!Warning]
>
> For this to work, you need to set the following headers on your server:
>
> `Cross-Origin-Opener-Policy: same-origin`
>
> `Cross-Origin-Embedder-Policy: require-corp`

```js
// In `main.js`.
const worker = new Worker('worker.js', { type: 'module' });
```

```js
// In `worker.js`.
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';

const start = (sqlite3) => {
console.log('Running SQLite3 version', sqlite3.version.libVersion);
const db =
'opfs' in sqlite3
? new sqlite3.oo1.OpfsDb('/mydb.sqlite3')
: new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');
console.log(
'opfs' in sqlite3
? `OPFS is available, created persisted database at ${db.filename}`
: `OPFS is not available, created transient database ${db.filename}`,
);
// Your SQLite code here.
};

const initializeSQLite = async () => {
try {
console.log('Loading and initializing SQLite3 module...');
const sqlite3 = await sqlite3InitModule();
console.log('Done initializing. Running demo...');
start(sqlite3);
} catch (err) {
console.error('Initialization error:', err.name, err.message);
}
};

initializeSQLite();
```

The `db` object above implements the
[Object-Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md).

### In the main thread (without OPFS):

```js
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';

const start = (sqlite3) => {
log('Running SQLite3 version', sqlite3.version.libVersion);
const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');
// Your SQLite code here.
};
const initializeSQLite = async () => {
try {
console.log('Loading and initializing SQLite3 module...');
const sqlite3 = await sqlite3InitModule();
console.log('Done initializing. Running demo...');
start(sqlite3);
} catch (err) {
console.error('Initialization error:', err.name, err.message);
}
};

initializeSQLite();
```

The `db` object above implements the
Only the worker OPFS implementations allow you to use the origin private file system (OPFS) storage
back-end. The `db` object in these examples implements the
[Object-Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md).

## Usage with vite
Expand Down Expand Up @@ -146,19 +90,6 @@ available on [StackBlitz](https://stackblitz.com/edit/vitejs-vite-ttrbwh?file=ma
See the list of [npm dependents](https://www.npmjs.com/browse/depended/@sqlite.org/sqlite-wasm) for
this package.

## Deploying a new version

(These steps can only be executed by maintainers.)

1. Manually trigger the [GitHub Actions workflow](../../actions/workflows/build-wasm.yml). By
default, it uses the latest SQLite tag. This pull request will contain the latest `sqlite3.wasm`
and related bindings.

2. Once the above pull request is validated and merged, update the version number in `package.json`,
reflecting the current [SQLite version number](https://sqlite.org/download.html) and add a build
identifier suffix like `-build1`. The complete version number should read something like
`3.41.2-build1`.

## Building the SQLite Wasm locally

1. Build the Docker image:
Expand All @@ -169,6 +100,34 @@ this package.

2. Run the build:

By default, this builds the full upstream npm bundle plus these omit-API variants. All variants
omit the deprecated Worker1 API:

- `core`: `omit-api="kvvfs OPFS vtab worker1"`, exported as
`@sqlite.org/sqlite-wasm/bundler/core`
- `core-vtab`: `omit-api="kvvfs OPFS worker1"`, exported as
`@sqlite.org/sqlite-wasm/bundler/vtab`
- `core-kvvfs`: `omit-api="OPFS vtab worker1"`, exported as
`@sqlite.org/sqlite-wasm/bundler/kvvfs`
- `core-opfs`: `omit-api="kvvfs opfs-wl opfs-sahpool vtab worker1"`, exported as
`@sqlite.org/sqlite-wasm/bundler/opfs`
- `core-opfs-wl`: `omit-api="kvvfs opfs opfs-sahpool vtab worker1"`, exported as
`@sqlite.org/sqlite-wasm/bundler/opfs-wl`
- `core-opfs-sahpool`: `omit-api="kvvfs opfs opfs-wl vtab worker1"`, exported as
`@sqlite.org/sqlite-wasm/bundler/sah-pool`

To customize the generated variants, set `SQLITE_WASM_OMIT_API_BUILDS` to a semicolon-separated
list of `name=api api` entries. Set it to an empty string to build only the full bundle. Custom
variants are written to `src/bin`; add them to `tsdown.config.ts` and `package.json` if they
should be published as package subpaths.

Only bundler-friendly JavaScript artifacts are kept for generated variants. They are written to
`src/bin` with their variant name in the filename, for example
`sqlite3-core-bundler-friendly.mjs`, and load the default `sqlite3.wasm` from the full npm bundle
build. The package build emits optimized copies into `dist` and exports the fixed variants under
the `/bundler` package subpaths shown above. If the selected SQLite ref does not support
`omit-api`, set `SQLITE_WASM_OMIT_API_BUILDS` to an empty string to build only the full bundle.

**Unix (Linux/macOS):**

```bash
Expand Down
2 changes: 1 addition & 1 deletion demos/in-worker-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"vite": "^8.2.2"
"vite": "^8.3.0"
}
}
2 changes: 1 addition & 1 deletion demos/kvvfs-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"vite": "^8.2.2"
"vite": "^8.3.0"
}
}
2 changes: 1 addition & 1 deletion demos/main-thread-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"vite": "^8.2.2"
"vite": "^8.3.0"
}
}
2 changes: 1 addition & 1 deletion demos/opfs-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"vite": "^8.2.2"
"vite": "^8.3.0"
}
}
2 changes: 1 addition & 1 deletion demos/opfs-wl-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"vite": "^8.2.2"
"vite": "^8.3.0"
}
}
2 changes: 1 addition & 1 deletion demos/sahpool-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"vite": "^8.2.2"
"vite": "^8.3.0"
}
}
2 changes: 1 addition & 1 deletion demos/sahpool-rsbuild-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"@rsbuild/core": "^2.2.3"
"@rsbuild/core": "^2.2.7"
}
}
2 changes: 1 addition & 1 deletion demos/sahpool-webpack-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@sqlite.org/sqlite-wasm": "file:../.."
},
"devDependencies": {
"webpack": "^5.110.3",
"webpack": "^5.111.0",
"webpack-cli": "^7.2.3",
"webpack-dev-server": "^6.0.0"
}
Expand Down
20 changes: 20 additions & 0 deletions docs/bundler-core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Bundler core omit-api build

Use this when you want the smallest browser bundler entry and only need the core SQLite APIs.

```ts
// Main thread or worker
import sqlite3InitModule from '@sqlite.org/sqlite-wasm/bundler/core';

const sqlite3 = await sqlite3InitModule();
const db = new sqlite3.oo1.DB(':memory:');

try {
db.exec('CREATE TABLE t(value); INSERT INTO t(value) VALUES (1)');
console.log(db.selectValue('SELECT value FROM t'));
} finally {
db.close();
}
```

This build omits Worker1, vtab helpers, kvvfs, OPFS, OPFS WebLocks, and OPFS SAH Pool.
23 changes: 23 additions & 0 deletions docs/bundler-kvvfs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Bundler kvvfs omit-api build

Use this when you want the key-value VFS backed by Web Storage.

```ts
// Main thread or worker
import sqlite3InitModule from '@sqlite.org/sqlite-wasm/bundler/kvvfs';

const sqlite3 = await sqlite3InitModule();
const dbName = 'file:my-kvvfs-db?vfs=kvvfs';
const db = new sqlite3.oo1.DB(dbName, 'c');

try {
db.exec('CREATE TABLE IF NOT EXISTS notes(body TEXT)');
db.exec({ sql: 'INSERT INTO notes(body) VALUES (?)', bind: ['hello from kvvfs'] });
console.log(db.selectValue('SELECT body FROM notes ORDER BY rowid DESC LIMIT 1'));
} finally {
db.close();
}
```

This build includes the core runtime and kvvfs. It omits Worker1, vtab helpers, OPFS, OPFS WebLocks,
and OPFS SAH Pool.
22 changes: 22 additions & 0 deletions docs/bundler-opfs-wl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Bundler OPFS WebLocks omit-api build

Use this in a Worker when you want the WebLocks-backed OPFS VFS.

```ts
// Worker
import sqlite3InitModule from '@sqlite.org/sqlite-wasm/bundler/opfs-wl';

const sqlite3 = await sqlite3InitModule();
const db = new sqlite3.oo1.OpfsWlDb('/app.sqlite3', 'ct');

try {
db.exec('CREATE TABLE IF NOT EXISTS events(name TEXT)');
db.exec({ sql: 'INSERT INTO events(name) VALUES (?)', bind: ['opened'] });
postMessage({ count: db.selectValue('SELECT count(*) FROM events') });
} finally {
db.close();
}
```

This build includes the core runtime and OPFS WebLocks. It omits Worker1, vtab helpers, kvvfs, OPFS,
and OPFS SAH Pool.
23 changes: 23 additions & 0 deletions docs/bundler-opfs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Bundler OPFS omit-api build

Use this in a dedicated Worker when you want the synchronous OPFS VFS.

```ts
// Worker
import sqlite3InitModule from '@sqlite.org/sqlite-wasm/bundler/opfs';

const sqlite3 = await sqlite3InitModule();
const db = new sqlite3.oo1.OpfsDb('/app.sqlite3', 'ct');

try {
db.exec('CREATE TABLE IF NOT EXISTS events(name TEXT)');
db.exec({ sql: 'INSERT INTO events(name) VALUES (?)', bind: ['opened'] });
postMessage({ count: db.selectValue('SELECT count(*) FROM events') });
} finally {
db.close();
}
```

Serve Worker pages with cross-origin isolation headers when the browser requires them. This build
includes the core runtime and OPFS. It omits Worker1, vtab helpers, kvvfs, OPFS WebLocks, and OPFS
SAH Pool.
23 changes: 23 additions & 0 deletions docs/bundler-sah-pool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Bundler OPFS SAH Pool omit-api build

Use this in a Worker when you want the OPFS SyncAccessHandle Pool VFS.

```ts
// Worker
import sqlite3InitModule from '@sqlite.org/sqlite-wasm/bundler/sah-pool';

const sqlite3 = await sqlite3InitModule();
const sahPool = await sqlite3.installOpfsSAHPoolVfs({});
const db = new sahPool.OpfsSAHPoolDb('/app.sqlite3');

try {
db.exec('CREATE TABLE IF NOT EXISTS events(name TEXT)');
db.exec({ sql: 'INSERT INTO events(name) VALUES (?)', bind: ['opened'] });
postMessage({ count: db.selectValue('SELECT count(*) FROM events') });
} finally {
db.close();
}
```

This build includes the core runtime and OPFS SAH Pool. It omits Worker1, vtab helpers, kvvfs, OPFS,
and OPFS WebLocks.
15 changes: 15 additions & 0 deletions docs/bundler-vtab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Bundler vtab omit-api build

Use this when you need the virtual table helper APIs and do not need any bundled VFS implementation.

```ts
// Main thread or worker
import sqlite3InitModule from '@sqlite.org/sqlite-wasm/bundler/vtab';

const sqlite3 = await sqlite3InitModule();

console.log(sqlite3.vtab); // virtual table helper namespace
```

This build includes the core runtime and vtab helpers. It omits Worker1, kvvfs, OPFS, OPFS WebLocks,
and OPFS SAH Pool.
22 changes: 22 additions & 0 deletions docs/main-thread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Main-thread browser example

Use this pattern when you do not need OPFS. It matches the main-thread example from the README and
uses a transient database.

```ts
// Main thread
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';

const sqlite3 = await sqlite3InitModule();
const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');

try {
db.exec('CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT)');
db.exec({ sql: 'INSERT INTO users(name) VALUES (?), (?)', bind: ['Ada', 'Linus'] });
console.log(db.selectObjects('SELECT * FROM users ORDER BY id'));
} finally {
db.close();
}
```

For OPFS-backed databases, prefer a Worker and one of the OPFS omit-api builds.
Loading