SQLite (native)
@sqb/sqlite is the SQB adapter for embedded SQLite, built on the runtime's own native SQLite
bindings — node:sqlite on Node.js, bun:sqlite on Bun — so it needs no native build step and
no separate driver package to install.
@sqb/sqlite requires Node.js >= 22.5 (or Bun), stricter than the rest of the project's
>= 20.0 requirement, because node:sqlite isn't available on older Node.js versions. If you
need to support older Node.js runtimes, or a browser/non-native environment, use
@sqb/sqljs instead.
Install
npm install @sqb/sqlite
@sqb/connect and @sqb/builder are peer dependencies pulled in transitively if you already
depend on them directly; otherwise install them alongside.
Registering the adapter
Importing @sqb/sqlite registers it as a side effect — there's nothing else to wire up:
import '@sqb/sqlite';
import { SqbClient } from '@sqb/connect';
const client = new SqbClient({
dialect: 'sqlite', // or driver: 'sqlite'
database: './mydb.sqlite',
});
Under the hood, @sqb/sqlite's entry point imports @sqb/sqlite-dialect (shared with
@sqb/sqljs — both generate standard SQLite SQL) and registers a SqliteAdapter instance with
AdapterRegistry. SqliteAdapter reports driver: 'sqlite' and dialect: 'sqlite'.
At runtime, the adapter detects whether it's running under Bun (globalThis.Bun present) or
Node.js and dynamically imports the matching driver module (bun:sqlite or node:sqlite)
accordingly — no configuration is needed to pick one.
Configuration
database is required — the adapter throws if it's missing. It's resolved as an absolute file
path, except for the special value :memory: (optionally suffixed, e.g. :memory:mydb), which
opens an in-memory database instead:
new SqbClient({ dialect: 'sqlite', database: ':memory:' });
There is no driverOptions passthrough for this adapter — only database is used to open the
connection.
Connection sharing
Multiple SqbClient/pool connections opened against the same non-memory database path share a
single underlying native database handle (reference-counted, closed once the last connection to
it closes), so concurrent connections to the same SQLite file don't each open a separate native
handle.
Feature notes
- Cursors: supported (
features.cursor: true) — see Cursors & Streaming. - Schemas: not supported — SQLite has no server-side schema concept.
RETURNING: SQLite supportsINSERT/UPDATE/DELETE ... RETURNINGnatively via the dialect, but the adapter still emulates it with a follow-upSELECT(matched viarowidfor inserts, or the originalWHEREclause for updates) rather than relying on it. Only the parameters that re-SELECTactually references are passed to it (fixed in v6.2.0 — earlier releases failed onUPDATE ... RETURNINGonce aSETvalue was bound as a parameter, becausenode:sqliterejects unknown named parameters).- Full-text search: the
Matchoperator renders as an FTS5MATCH(since v6.1.0) — see@sqb/sqlite-dialect. - Statements without a result set (DDL,
PRAGMA,INSERT OR REPLACE, ...) are run with the driver'srun()rather than a lazy iterator, androwsAffectedis reported forINSERT/REPLACE/UPDATE/DELETE(fixed in v6.1.0 — earlier releases silently skipped such statements when executed throughclient.execute()).
Migrator support
Supported since v6.0.8 — see Running migrations.
SqliteMigrationAdapter is selected by connection.dialect: 'sqlite' (with driver unset or
'sqlite'; driver: 'sqljs' selects the sql.js adapter instead). SQLite has no schema
object, so infoSchema is only a table-name prefix and $(schema) resolves to main, SQLite's
always-present default database name. A whole multi-statement script runs in one call, and
locking is a no-op — SQLite is embedded and single-process, with no server to arbitrate a lock
between clients. SQLite runs DDL inside transactions, so it supports transaction: 'run'/'migration' and dryRun (since v6.3.0 — see Transactional runs).
See also
- Choosing a Database Adapter
@sqb/sqljs— the WebAssembly alternative for browsers or older runtimesSqliteAdapterAPI reference- Creating a Client