bunostrdb docs

Bun FFI bindings for nostrdb — the embedded nostr database backed by LMDB. Linux x86_64 + Bun only.
Snippets import from "bunostrdb" — the library workspace (packages/bunostrdb), linked automatically by bun install at the repo root. The CLI ships separately as bunostrdb-cli.
Quick overview
BunNdb
The database handle. Opens (creating) an LMDB directory, ingests events, queries, subscribes, and searches.
// @ts-nocheck
import { buildDraftNote, BunNdb } from "bunostrdb";
{
using ndb = new BunNdb("./data");
const { event } = buildDraftNote("hello local world");
ndb.processEvent(JSON.stringify(["EVENT", "sub1", event]));
await ndb.waitForNoteById(event.id); // ingestion is async — wait for commit
const note = ndb.getNoteById(event.id);
console.log(note?.content);
} // always destroyed at scope exit — see [Resource management](./resource-management.md)Filters
FilterBuilder assembles native filters; build() transfers ownership to a Filter you must destroy.
// @ts-nocheck
import { buildDraftNote, BunNdb, FilterBuilder, ingestDraft } from "bunostrdb";
{
using ndb = new BunNdb("./data.filters");
const draft = buildDraftNote("hello filtered world");
await ingestDraft(ndb, draft.eventJson);
using filter = new FilterBuilder().kinds([1]).authors([draft.event.pubkey]).limit(10).build();
const notes = ndb.query([filter], 10);
console.log(`found ${notes.length} notes`);
}Subscriptions
Live ingestion notifications: subscribe, then poll or await matching notes. Ingestion is asynchronous — processEvent queues work; the subscription tells you when it lands.
// @ts-nocheck
import { buildDraftNote, BunNdb, FilterBuilder } from "bunostrdb";
{
using ndb = new BunNdb("./data.subs");
// Subscribe first — the subscription observes notes committed after it exists.
const subId = ndb.subscribe([new FilterBuilder().kinds([1])]);
const { event } = buildDraftNote("hello live world");
ndb.processEvent(JSON.stringify(["EVENT", "sub1", event]));
await ndb.waitForNotes(subId);
console.log(ndb.pollForNotes(subId, 32));
}Notes & tags
Typed access to parsed notes: content, pubkey, timestamps, and tag iteration without touching raw JSON.
// @ts-nocheck
import { buildDraftNote, BunNdb, ingestDraft } from "bunostrdb";
{
using ndb = new BunNdb("./data.tags");
const first = buildDraftNote("original note");
await ingestDraft(ndb, first.eventJson);
const reply = buildDraftNote("a reply", { tags: [["e", first.id]] });
await ingestDraft(ndb, reply.eventJson);
const note = ndb.getNoteById(reply.id);
for (const [name, ...values] of note?.tags ?? []) {
if (name === "e") console.log("reply to", values[0]);
}
}Drafts
Local-only events: mint an ephemeral identity, sign, ingest, and search — never published anywhere.
// @ts-nocheck
import { BunNdb, buildDraftNote, ingestDraft, searchDrafts } from "bunostrdb";
{
using ndb = new BunNdb("./data.drafts");
const draft = buildDraftNote("hello local world");
const id = await ingestDraft(ndb, draft.eventJson);
console.log("stored draft", id, searchDrafts(ndb, "hello").length);
}CLI
Every library capability above is also a subcommand, scriptable over pipes: ingest (--event accepts JSON, a file, or - for stdin), query, get-note, get-profile, draft-note, draft-reaction, draft-profile, search.
bun run cli -- draft-note --db ./data.drafts --content "my first local draft"
bun run cli -- search --db ./data.drafts --query "local draft" --limit 20Next steps
- Getting started — install, open your first DB, and the ownership rules that keep the FFI layer sound.
- Resource management —
using/await usingfor every native handle. - Integrations — feed relay events in, script the CLI, local-first drafts, and the browser companion package.
- Personal draft DB (CLI) — the full CLI walkthrough. mapped to bunostrdb APIs.
- Comparison vs nak vs deed — where bunostrdb wins (in-process queries, batch ingest) and where it doesn't (one-shot startup, streaming crypto).
These pages are static VitePress output — no server, no iframes.
Support
If bunostrdb is useful, support development with any amount using Monero:

8AfaZJa3HRnS4F9yRzRK9iDcVPm17WA33EEZjWfREkkoUGWbLfA79aeSWoAj21B7swMW9bb8iWdgw8mtjJ5y4yMT7z6AmCc