You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today LibreDB ships through a single channel: the npm package @libredb/libredb (ESM-only, Node 22+/Bun, zero runtime dependencies),
consumed via import in TypeScript/JavaScript projects. This issue tracks
exploring additional packaging and distribution channels so LibreDB is
reachable in more runtimes and usage shapes.
This is a deferred / exploratory issue — no immediate implementation is
planned. It captures the analysis so we can pick it up later.
Explicit non-goal: server / network engine
LibreDB is, by design, an embedded, in-process library (SQLite-style),
not a server/daemon (Postgres-style). The manifesto and locked design
decisions state this directly:
docs/DESIGN.md: "LibreDB competes with the database textbook and the
'I'll just use a Map for now' hack — not with Postgres."
ARCHITECTURE.md (§10.1): "Concurrent multi-process access, replication,
or a networked client/server — it is embedded and in-process."
Therefore a networked client/server "engine" mode is out of scope for
this issue. It would reopen the concurrency/isolation model and contradict
the manifesto. The directions below all preserve the embedded core.
JSR (jsr.io): publish the same library to the TS-native registry so
Deno/Bun/Node all consume it. isolatedDeclarations: true is already on,
which satisfies JSR "fast types" — a strong fit. Needs a jsr.json with exports pointing at src/index.ts, version kept in sync with package.json.
CDN / browser: esm.sh already serves the ESM package and auto-shims node:fs, so in-memory usage (open() with no path) works in the browser
today. Action: document it; add a smoke test.
(Decision point) True browser-native, shim-free support: src/core.ts
statically imports node:fs at module top level (line 23), which fails in
raw browser ESM (without a CDN shim). Making this shim-free would require
moving nodeFileSystem() into a separate adapter module and resolving the
Node default via package.jsonexports conditions — without breaking the
synchronous API or the open({ path }) ergonomics on Node. This may push
against the "small core" principle; needs a deliberate decision before
doing it.
2. CLI tool (npx libredb)
A thin shell over the public API (open, lenses, catalog) to inspect a .libredb file — like SQLite's sqlite3 command. Does not change the
embedded core. Proposed surface (keep narrow):
Implementation notes: new src/cli.ts using Node/Bun built-in parseArgs
(stay zero-dependency); "bin": { "libredb": "./dist/cli.js" }; compile cli.ts in tsconfig.build.json.
3. Standalone single-file binary + Docker (depends on #2)
Binary: bun build --compile src/cli.ts --outfile libredb produces a
self-contained executable (no Node required); cross-compile via --target.
Distributed as GitHub Release assets, not added to the npm package
(files: ["dist"] stays as-is).
Docker: a minimal Dockerfile wrapping the binary. Note honestly that
for an embedded DB, Docker is a portable CLI shell, not a server — it
needs a volume mount (-v $PWD:/data) and runs no persistent service.
Constraints to respect when implementing later
100% coverage gate (bunfig.toml): every new runtime line (CLI
included) must be tested or bun run gate fails.
Changeset policy (CLAUDE.md): changes that reach the published
package (CLI, exports changes) are user-facing → require a changeset.
Repo-only changes (CI, docs, binary/Docker artifacts) do not.
Each direction is independently shippable; none requires the others except
binary/Docker depending on the CLI.
Required first step: detailed research before any implementation
Before starting any development, a thorough investigation is mandatory: given
that LibreDB is an embedded, FoundationDB-style architecture (one small
ordered key-value core with thin model lenses on top), through which other
channels can it be delivered to users — package, SDK, image, CLI, etc.? The
research should map each candidate channel to how well it fits the embedded,
single-process, zero-dependency design before we commit to building anything.
Summary
Today LibreDB ships through a single channel: the npm package
@libredb/libredb(ESM-only, Node 22+/Bun, zero runtime dependencies),consumed via
importin TypeScript/JavaScript projects. This issue tracksexploring additional packaging and distribution channels so LibreDB is
reachable in more runtimes and usage shapes.
This is a deferred / exploratory issue — no immediate implementation is
planned. It captures the analysis so we can pick it up later.
Explicit non-goal: server / network engine
LibreDB is, by design, an embedded, in-process library (SQLite-style),
not a server/daemon (Postgres-style). The manifesto and locked design
decisions state this directly:
docs/DESIGN.md: "LibreDB competes with the database textbook and the'I'll just use a
Mapfor now' hack — not with Postgres."ARCHITECTURE.md(§10.1): "Concurrent multi-process access, replication,or a networked client/server — it is embedded and in-process."
Therefore a networked client/server "engine" mode is out of scope for
this issue. It would reopen the concurrency/isolation model and contradict
the manifesto. The directions below all preserve the embedded core.
Candidate directions
1. JSR + CDN / browser reach (lowest effort, additive)
jsr.io): publish the same library to the TS-native registry soDeno/Bun/Node all consume it.
isolatedDeclarations: trueis already on,which satisfies JSR "fast types" — a strong fit. Needs a
jsr.jsonwithexportspointing atsrc/index.ts, version kept in sync withpackage.json.node:fs, so in-memory usage (open()with no path) works in the browsertoday. Action: document it; add a smoke test.
src/core.tsstatically imports
node:fsat module top level (line 23), which fails inraw browser ESM (without a CDN shim). Making this shim-free would require
moving
nodeFileSystem()into a separate adapter module and resolving theNode default via
package.jsonexportsconditions — without breaking thesynchronous API or the
open({ path })ergonomics on Node. This may pushagainst the "small core" principle; needs a deliberate decision before
doing it.
2. CLI tool (
npx libredb)A thin shell over the public API (
open, lenses,catalog) to inspect a.libredbfile — like SQLite'ssqlite3command. Does not change theembedded core. Proposed surface (keep narrow):
libredb inspect <file>— keyspace/catalog summary (lenses, collections,tables, counts).
libredb get/scan <file> [key|prefix]— kv reads.libredb stats <file>— size, WAL status.libredb repl <file>— interactive read shell.Implementation notes: new
src/cli.tsusing Node/Bun built-inparseArgs(stay zero-dependency);
"bin": { "libredb": "./dist/cli.js" }; compilecli.tsintsconfig.build.json.3. Standalone single-file binary + Docker (depends on #2)
bun build --compile src/cli.ts --outfile libredbproduces aself-contained executable (no Node required); cross-compile via
--target.Distributed as GitHub Release assets, not added to the npm package
(
files: ["dist"]stays as-is).Dockerfilewrapping the binary. Note honestly thatfor an embedded DB, Docker is a portable CLI shell, not a server — it
needs a volume mount (
-v $PWD:/data) and runs no persistent service.Constraints to respect when implementing later
bunfig.toml): every new runtime line (CLIincluded) must be tested or
bun run gatefails.CLAUDE.md): changes that reach the publishedpackage (CLI,
exportschanges) are user-facing → require a changeset.Repo-only changes (CI, docs, binary/Docker artifacts) do not.
Suggested ordering
Each direction is independently shippable; none requires the others except
binary/Docker depending on the CLI.
Required first step: detailed research before any implementation
Before starting any development, a thorough investigation is mandatory: given
that LibreDB is an embedded, FoundationDB-style architecture (one small
ordered key-value core with thin model lenses on top), through which other
channels can it be delivered to users — package, SDK, image, CLI, etc.? The
research should map each candidate channel to how well it fits the embedded,
single-process, zero-dependency design before we commit to building anything.