Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
@worlds/sqlite
Local node:sqlite durable backend for the Worlds client
(@worlds/sdk) — single-process, local-file
storage with optional sqlite-vec extension for vector search.
Part of the Worlds durable-backend family alongside @worlds/libsql (Turso),
@worlds/postgres, and @worlds/cloudflare. The provider-strategy vocabulary
is backend-internal (per the de-escalated seam decision,
worlds-sdk-ts#170);
cross-backend interchangeability lives at the @worlds/sdk WorldsSdk seam.
Status
Two layers (plan: worlds-sqlite#1):
- Layer 1 — RDF/JS quad primitive (
SqliteStore): landed. The store moved here from@wazoo/sparql-engine/sqlite(packaged with the worlds impl per the ecosystem pattern —LibsqlRdfjsStorelives in@worlds/libsql,PostgresRdfjsStorein@worlds/postgres), re-based onn3's DataFactory (the@worlds/sdkchoice) with term identity parity-tested against the engine. Published as@worlds/sqlite(root +./rdfjs-storesubpath). - Layer 2 — Worlds impl (
createSqliteWorldsSdk): landed. The full L2 SDK surface shipped as part of the durable-backend parity campaign (worlds-sqlite#7, tracked on workspace#59): FTS5 keyword search plus optionalsqlite-vechybrid search (RRFk=60), graceful keyword-only degradation when the extension is unavailable, and acreateSqliteWorldsSdkfactory mirroringcreateLibsqlSdk.
The SqliteStore quad primitive moved here from
@wazoo/sparql-engine (the ./sqlite
subpath it shipped in v0.3.x, graduated via
sparql-engine#56). It
satisfies the engine's createTransaction hook with no cross-package import;
the worlds search layer composes on top (Layer 2).
Install
Package managers
# Deno (first-class JSR support) deno add jsr:@worlds/sqlite # Bun / npm / pnpm / Yarn (via JSR npm compatibility layer) npx jsr add @worlds/sqlite
CDN (browser / no build step)
esm.sh serves JSR packages as ES modules — no install, no bundler needed.
import { SqliteStore } from "https://esm.sh/jsr/@worlds/sqlite@0.4.0";
With an import map:
<script type="importmap"> { "imports": { "@worlds/sqlite": "https://esm.sh/jsr/@worlds/sqlite@0.4.0" } } </script> <script type="module"> import { SqliteStore } from "@worlds/sqlite"; </script>
Pin to an exact build for deterministic caching:
import { SqliteStore } from "https://esm.sh/jsr/@worlds/sqlite@0.4.0?pin=v1724100000";
Surface
- Landed (Layer 1):
SqliteStore(durablerdfjs.Storeovernode:sqlite, STRICT table, WAL + busy_timeout, term-keyed rows, lossless RDF-star payloads,createTransaction()),MemoryStream, term identity (termKey/sameRdfTerm), crash-recovery + term-key-parity suites. - Landed (Layer 2):
createSqliteWorldsSdk(root export) plus./quad-store,./search-index, and./schemasubpaths —SqliteQuadStore,SqliteSearchIndex/SqliteSearchIndexProjector/SqliteSearchQueryBuilder(FTS5 + optional sqlite-vec hybrid with JS-side RRF1/(60+rank)),SqliteSchemaBuilder, andcommitPatchToSqlite(content-addressed dedup, replace-mode wipe, chunked batches). Keyword-only FTS5 is fully functional without thesqlite-vecextension. - Landed (
./sql-core): the driver-free SQL plan layer shared across the SQLite-family backends —sanitizeFtsQuery/stopwords,buildChunkFtsValue,buildSearchResultId, thechunks/chunks_ftsDDL emitters, keyword FTS5 branch plans, filter-clause helpers, and theSqlStatementplan type. See below.
This repo is the source of truth for SQLite-family SQL logic: it is the
easiest backend to test locally (synchronous node:sqlite), so the shared
query/table logic lives here and downstream SQLite-family backends
(@worlds/libsql today; D1 later) consume it via the ./sql-core subpath. The
quad storage layout (term-key hexastore here vs column-per-position rows in
libsql) and each vector-search dialect (vec0 vs native libsql vectors)
intentionally stay backend-local.
SQL core
@worlds/sqlite/sql-core exports pure, driver-free building blocks: every
symbol emits inert {sql, args} plans or plain strings — no database handle, no
I/O. Backends execute the plans through their own connection drivers, which is
why synchronous node:sqlite and asynchronous LibSQL can share the same
emitters. The guardrail is enforced in CI by deno task sql-core:purity
(allowlist-based import check); keep new sql-core modules on that allowlist
(@worlds/sdk, @wazoo/sparql-engine, @rdfjs/types, intra-package imports,
and @std/assert in tests only).
Setup
npx jsr add @worlds/sqlite
License
TBD — match sibling Worlds packages.
Add Package
deno add jsr:@worlds/sqlite
Import symbol
import * as sqlite from "@worlds/sqlite";
Import directly with a jsr specifier
import * as sqlite from "jsr:@worlds/sqlite@^0.6.0";