npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reddb-io/sdk

v1.5.0

Published

Official embedded RedDB SDK — launches a local red binary over stdio JSON-RPC. Use @reddb-io/client for remote HTTP, gRPC, and RedWire.

Downloads

2,234

Readme

@reddb-io/sdk

Official RedDB SDK for JavaScript and TypeScript. Speaks JSON-RPC 2.0 over stdio to a local red binary, which is downloaded automatically on install. Works in Node 18+, Bun and Deno (via npm: specifier) — same package, no per-runtime fork.

Use this package when your application should run an embedded local RedDB engine. For remote HTTP, gRPC, or RedWire connections, install @reddb-io/client instead. If you just want to launch the CLI from npm, use:

npx @reddb-io/cli@latest version
npx @reddb-io/cli@latest server --http-bind 127.0.0.1:8080 --path ./data.rdb

Install

pnpm add @reddb-io/sdk
# or
npm install @reddb-io/sdk
# or
bun add @reddb-io/sdk

In Deno:

import { connect } from 'npm:@reddb-io/sdk'

The postinstall script downloads the matching red binary from GitHub Releases into node_modules/@reddb-io/sdk/bin/. If your environment blocks postinstall scripts or has no network, set REDDB_BINARY_PATH=/path/to/red and the driver will use that instead.

Quickstart

import { connect } from '@reddb-io/sdk'

const db = await connect('memory://')        // ephemeral
// or:  await connect('file:///var/lib/reddb/data.rdb')   // persisted

await db.insert('users', { name: 'Alice', age: 30 })
await db.bulkInsert('users', [{ name: 'Bob' }, { name: 'Carol' }])

const result = await db.query('SELECT * FROM users')
console.log(result.rows)

const doc = await db.documents.insert('events', {
  event_type: 'login',
  attempts: 1,
})
await db.documents.patch('events', doc.rid, { reviewed: true })

await db.query('CREATE KV settings')
const kv = db.kv('settings')
await kv.put('characters:hansel', 'crumbs')
console.log(await kv.get('characters:hansel'))

await db.close()

TypeScript is the same API:

import { connect, RedDBError } from '@reddb-io/sdk'

const db = await connect('file:///var/lib/reddb/data.rdb')

try {
  const result = await db.query('SELECT * FROM users LIMIT 10')
  console.log(result.rows)
} catch (err) {
  if (err instanceof RedDBError) {
    console.error(err.code, err.message)
  }
}

await db.close()

For the SQL/RQL grammar that db.query() accepts, see docs/reference/sql-1-0-x.md.

Transactions

This driver supports both transaction forms from the SDK Helper Spec (§7): the imperative begin / commit / rollback trio and the callback form.

Callback formdb.transaction(callback) (or db.tx().run(callback)):

const userId = await db.transaction(async (tx) => {
  const inserted = await tx.insert('users', { name: 'Ada' })
  await tx.query('INSERT INTO audit (action) VALUES ($1)', 'created user')
  return inserted.rid
})

The wrapper sends BEGIN, commits when the callback resolves, and rolls back when the callback or a tx.query() / tx.insert() call throws.

Imperative formdb.tx() returns a transaction handle:

const tx = db.tx()
await tx.begin()
try {
  await db.query("INSERT INTO audit (action) VALUES ('created user')")
  await tx.commit()
} catch (err) {
  await tx.rollback()
  throw err
}

begin / commit / rollback each resolve to a QueryResult. A nested tx.run() (or db.transaction()) on the same connection is rejected with INVALID_ARGUMENT (NESTED_TX_NOT_SUPPORTED for the legacy db.transaction() shortcut) — callers wanting savepoints issue them directly via tx.query(). Open another connect() handle for independent concurrent transactions.

Connection URIs

| URI | Mode | |----------------------------|--------------------------------------| | memory:// | Ephemeral, in-memory database | | file:///absolute/path | Embedded engine, persisted to disk |

Remote URIs such as http://..., red://..., and grpc://... are rejected with EMBEDDED_ONLY. Use @reddb-io/client for those transports.

API

connect(uri, options?) → Promise<RedDB>

Spawns red rpc --stdio with arguments derived from the URI, attaches a JSON-RPC client to its stdin/stdout, then returns a connection handle.

Options:

  • binary — override the red binary path. Defaults to bin/red next to the package, or REDDB_BINARY_PATH env var if set.

Examples:

import { connect } from '@reddb-io/sdk'

const db = await connect('memory://')
const persisted = await connect('file:///tmp/app.rdb')
const custom = await connect('memory://', { binary: '/usr/local/bin/red' })

db.query(sql, ...params) → Promise<{ statement, affected, columns, rows }>

Bind user values with $1, $2, ... placeholders. The variadic form is the preferred API; the older db.query(sql, paramsArray) form remains supported.

const result = await db.query(
  'SELECT * FROM users WHERE id = $1 AND name = $2',
  42,
  'Alice',
)

db.execute(sql, ...params) is an alias for statements where the affected row count is the primary result.

ASK '...' returns the ASK envelope directly:

const answer = await db.query("ASK 'why did deploy fail?'")
answer.answer
answer.citations
answer.sources_flat
answer.validation
answer.cache_hit
answer.cost_usd

ASK '...' STREAM notifications are not wired over the JS stdio JSON-RPC client yet. Use the HTTP streaming API for incremental ASK frames; stdio currently supports materialised cursor batching through query.open / query.next, which is separate from ASK token streaming.

db.insert(collection, payload) → Promise<{ affected, rid, id }>

id is a legacy alias for rid.

db.bulkInsert(collection, payloads) → Promise<{ affected, rids, ids }>

ids is a legacy alias for rids.

db.get(collection, rid) → Promise<{ entity }>

db.delete(collection, rid) → Promise<{ affected }>

db.documents

Document helpers follow the SDK Helper Spec:

const inserted = await db.documents.insert('events', {
  event_type: 'login',
  details: { ip: '10.0.0.7' },
})

const event = await db.documents.get('events', inserted.rid)
const page = await db.documents.list('events', {
  filter: "event_type = 'login'",
  limit: 10,
})
const updated = await db.documents.patch('events', inserted.rid, {
  reviewed: true,
})
await db.documents.delete('events', inserted.rid)

documents.insert() creates the document collection when needed. Patch is a top-level merge: unrelated fields survive. An empty patch raises INVALID_ARGUMENT. documents.delete returns { affected, deleted } and NEVER raises on a missing rid (returns { affected: 0, deleted: false }).

db.kv(collection?)

KV helpers preserve exact keys, including namespaced keys with :.

await db.query('CREATE KV settings')
const kv = db.kv('settings')

await kv.set('characters:hansel', 'crumbs')  // `put` is a back-compat alias
await kv.get('characters:hansel')        // 'crumbs'   (null when missing)
await kv.exists('characters:hansel')     // { exists: true }
await kv.list({ prefix: 'characters:' }) // { items: [{ key, value }] }
await kv.delete('characters:hansel')     // { affected, deleted }

A kv.get of a missing key returns null (never NOT_FOUND). kv.delete returns the { affected, deleted } envelope; deleting a missing key is not an error and returns { affected: 0, deleted: false }.

db.queues (alias db.queue)

Queue helpers cover the embedded FIFO workflow. The spec-canonical namespace is the plural db.queues; db.queue remains as an alias.

await db.queues.create('jobs')           // CREATE QUEUE IF NOT EXISTS (idempotent)
await db.queues.push('jobs', { task: 'ship' })
await db.queues.peek('jobs')             // does NOT decrement length
await db.queues.pop('jobs')              // empty queue → [] (never NOT_FOUND)
await db.queues.len('jobs')
await db.queues.purge('jobs')

SDK Helper Spec conformance

This driver implements SDK Helper Spec v1.0 (docs/spec/sdk-helpers.md). The version is exposed for cross-driver CI dashboards:

import { HELPER_SPEC_VERSION } from '@reddb-io/sdk'
HELPER_SPEC_VERSION   // '1.0'
db.helperSpecVersion  // '1.0'

Return envelopes (wire field names preserved when serialised to JSON):

| Envelope | Fields | |---------------------|---------------------------------------------------| | QueryResult | statement, affected, columns, rows | | InsertResult | affected (1), rid (id legacy alias) | | BulkInsertResult | affected, rids in input order (ids alias) | | DeleteResult | affected, deleted (= affected > 0) | | ExistsResult | exists |

Transaction support: imperative (db.tx().begin/commit/rollback) and callback (db.transaction(cb) / db.tx().run(cb)). Nested callbacks reject with INVALID_ARGUMENT.

Case matrix (spec §12 — ported verbatim in test/conformance.test.mjs):

| Case ID | Status | |--------------------------------------|-------------| | meta.spec_version | supported | | generic.query.no_params | supported | | generic.query_with.params | supported | | generic.insert.rid | supported | | generic.bulk_insert.rids | supported | | generic.delete | supported | | documents.crud_nested_patch | supported | | documents.delete_missing_no_error | supported | | documents.patch_empty_rejects | supported | | kv.exact_key_round_trip | supported | | kv.missing_get_returns_none | supported | | kv.delete_returns_envelope | supported | | queues.fifo_peek_pop_len | supported | | queues.empty_pop_returns_empty | supported | | queues.purge_resets_len | supported | | tx.commit_persists | supported | | tx.rollback_discards | supported | | errors.invalid_argument.empty_sql | supported | | errors.not_found.document_get | supported | | wire.probabilistic.hll_round_trip | provisional (SQL via db.query) | | wire.vectors.sql_round_trip | reachable via db.query (no v1.0 case) | | wire.graph.sql_round_trip | reachable via db.query (no v1.0 case) | | wire.timeseries.sql_round_trip | reachable via db.query (no v1.0 case) |

Out-of-scope in v1.0 (reach via raw db.query until v1.1, per spec): first-class vectors.*, graph.*, timeseries.*, and probabilistic.* helpers; KV TTL (kv.expire) and gRPC watch; priority queues, consumer groups, dead-letter routing; transaction isolation-level arguments and cross-shard transactions; JSON Patch / nested / array-positional document patches (top-level merge only).

Run the conformance harness against a locally built binary:

cargo build                                   # produces target/debug/red
node drivers/js/test/conformance.test.mjs
# or: REDDB_BINARY_PATH=/path/to/red node drivers/js/test/conformance.test.mjs

The harness (and the README-examples test) self-skip with exit 0 when no binary is present, so pnpm test stays green on machines without a build.

db.health() → Promise<{ ok, version }>

db.version() → Promise<{ version, protocol }>

db.close() → Promise<void>

Sends close to the binary, waits for it to exit. Calls after close() reject with RedDBError('CLIENT_CLOSED', ...).

Errors

All RPC failures throw RedDBError:

import { RedDBError } from '@reddb-io/sdk'

try {
  await db.query('NOT VALID SQL')
} catch (err) {
  if (err instanceof RedDBError) {
    console.error(err.code)    // 'QUERY_ERROR'
    console.error(err.message) // server-provided detail
    console.error(err.data)    // optional structured data
  }
}

Stable error codes:

| code | when | |-------------------|------------------------------------------------------------| | PARSE_ERROR | Server got malformed JSON (driver bug, please report) | | INVALID_REQUEST | Missing field or unknown method | | INVALID_PARAMS | params didn't match the method schema | | QUERY_ERROR | SQL parse, type or constraint error | | NOT_FOUND | Entity / collection does not exist | | INTERNAL_ERROR | Server caught a panic | | CLIENT_CLOSED | Driver-side: call after close() or unexpected EOF | | UNSUPPORTED_SCHEME | URI scheme not yet supported by the driver |

Limits

  • stdio IPC overhead. Each call is a JSON serialize, write, parse, read round-trip. For most apps (web servers, scripts, ETL) this is invisible. For very high-throughput single-process ingestion, use the embedded Rust crate reddb directly.
  • No edge runtimes. Cloudflare Workers, Vercel Edge and the browser have no subprocess support. If you need RedDB there, wait for the planned HTTP transport (see PLAN_DRIVERS.md).
  • One process per connection. No connection pooling yet. If you need concurrent independent transactions, open multiple connect() handles.

Testing locally

cargo build --bin red       # at repo root
cd drivers/js
node test/smoke.test.mjs

Same test runs in Bun and Deno:

bun test/smoke.test.mjs
deno run -A test/smoke.test.mjs

Remote Deploy

When you're ready to point JavaScript code at a production RedDB cluster, use @reddb-io/client. The SDK package is embedded-only and intentionally rejects remote URIs.

Public-surface support

Generated from docs/conformance/public-surface-contract-matrix.json by scripts/gen-docs-from-matrix.mjs. Do not edit between the markers by hand — run node scripts/gen-docs-from-matrix.mjs --write. The matrix is the source of truth; this block can never claim more than it, and CI (docs-matrix) fails on drift.

Driver-helper (SDK Helper Spec v1.0) support for every public promise. A helper not marked supported here is not promised by this driver.

| Promise | driver_helpers | | --- | --- | | PSC-001 — RedDB is one multi-model database (tables, graph, KV, timeseries, probabilistic, vector, queue, documents) backed by a single file. | ✅ supported | | PSC-002 — MATCH supports node, edge, label, property, and LIMIT projections. | ✅ supported | | PSC-003 — GRAPH algorithms accept semantic identifiers, limits, ordering, and return stable rich rows. | ❌ unsupported | | PSC-004 — INSERT creates rows, documents, and native timeseries points. | ✅ supported | | PSC-005 — HLL/SKETCH/FILTER expose write and read commands for cardinality, frequency, and membership. | ⚠️ partial | | PSC-006 — Timeseries stores timestamped metrics with tags and supports query/readback. | ⚠️ partial | | PSC-007 — Documents are first-class: create, read, update, delete, and SQL analytics over JSON. | ✅ supported | | PSC-008 — KV helpers expose get/put/delete; get of a missing key returns null, delete reports affected. | ✅ supported | | PSC-009 — Queue helpers expose create/push/peek/pop/len/purge with FIFO semantics; empty pop is not an error. | ✅ supported | | PSC-010 — Transactions are imperative (begin/commit/rollback) plus a run(callback) form; empty SQL rejects with INVALID_ARGUMENT. | ✅ supported | | PSC-011 — SQL aggregate, projection, expression, and mutation behaviour matches ordinary SQL expectations where advertised. | ✅ supported | | PSC-012 — Server transports expose the same query contract as embedded (HTTP, RedWire, gRPC parity). | ✅ supported | | PSC-013 — Official drivers implement the SDK Helper Spec v1.0 conformance suite (all 22 §12 case IDs). | ✅ supported | | PSC-014 — ASK / SEARCH semantic surfaces return ranked results with stable shape. | ⚠️ partial |

Status legend: ✅ supported · ⚠️ partial (known gaps) · ❌ unsupported.