LogoPear Docs
ReferenceBuilding blocks

Hyperbee

Append-only B-tree on Hypercore for sorted key/value data.

stable

Hyperbee stores sorted key/value entries in an append-only B-tree backed by Hypercore. Use it when you need ordered lookups, range scans, atomic batches, namespaces, and point-in-time snapshots over one replicated log.

Install

npm i hyperbee

Quickstart

import Hypercore from 'hypercore'
import Hyperbee from 'hyperbee'

const core = new Hypercore('./bee-storage')
const db = new Hyperbee(core, {
  keyEncoding: 'utf-8',
  valueEncoding: 'json'
})

await db.ready()
await db.put('config', { theme: 'dark', retries: 3 })

const entry = await db.get('config')
console.log(entry.value.theme)

await db.close()

API Reference

Constructor and readiness

new Hyperbee(core, [options])

API definition on GitHub

  • Signature: const db = new Hyperbee(core, [options]) (GitHub)
  • Parameters: core is the backing Hypercore; options.keyEncoding and options.valueEncoding accept 'binary', 'utf-8', 'ascii', 'json', or another abstract encoding. (GitHub)
  • Returns: A Hyperbee instance that reads and writes entries on top of the supplied core. (GitHub)
  • Example: const db = new Hyperbee(core, { keyEncoding: 'utf-8', valueEncoding: 'json' })

Read and diff streams sort keys by their encoded byte values, so choose keyEncoding deliberately if lexicographic order matters.

await db.ready()

API definition on GitHub

  • Signature: await db.ready() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves when the bee has loaded enough internal state for synchronous properties such as db.version. (GitHub)
  • Example: await db.ready()

Properties and identity

db.core

API definition on GitHub

  • Signature: db.core (GitHub)
  • Returns: The underlying Hypercore instance. (GitHub)
  • Example: swarm.join(db.core.discoveryKey)

db.version

API definition on GitHub

  • Signature: db.version (GitHub)
  • Returns: The current modification count for the bee, which is useful as a version identifier for snapshots and diffs. (GitHub)
  • Example: const snapshot = db.checkout(db.version)

db.id

API definition on GitHub

  • Signature: db.id (GitHub)
  • Returns: A z-base-32 string derived from the public key that identifies this bee. (GitHub)
  • Example: console.log(db.id)

db.key

API definition on GitHub

  • Signature: db.key (GitHub)
  • Returns: The public key buffer for the bee. (GitHub)
  • Example: console.log(db.key.toString('hex'))

db.discoveryKey

API definition on GitHub

  • Signature: db.discoveryKey (GitHub)
  • Returns: A derived key suitable for peer discovery without exposing db.key. (GitHub)
  • Example: swarm.join(db.discoveryKey)

db.writable

API definition on GitHub

  • Signature: db.writable (GitHub)
  • Returns: true when this process can append writes to the backing core. (GitHub)
  • Example: if (db.writable) await db.put('mode', 'writer')

db.readable

API definition on GitHub

  • Signature: db.readable (GitHub)
  • Returns: true while the bee is open and readable. (GitHub)
  • Example: if (!db.readable) throw new Error('bee is closed')

Writes and batches

await db.put(key, [value], [options])

API definition on GitHub

  • Signature: await db.put(key, [value], [options]) (GitHub)
  • Parameters: key uses keyEncoding; value is optional and uses valueEncoding; options.cas(prev, next) can accept or reject updates when a key already exists. (GitHub)
  • Returns: Resolves when the write has been appended. (GitHub)
  • Example: await db.put('user:1', { name: 'Ada' })

The cas comparator receives the current node as prev and the potential new node as next. It runs only when the key already exists.

await db.del(key, [options])

API definition on GitHub

  • Signature: await db.del(key, [options]) (GitHub)
  • Parameters: key uses keyEncoding; options.cas(prev) can veto the delete when the current value should be preserved. (GitHub)
  • Returns: Resolves when the delete marker has been appended. (GitHub)
  • Example: await db.del('user:1')

The delete comparator runs only when the key exists. Deleting a missing key succeeds without calling cas.

const batch = db.batch()

API definition on GitHub

  • Signature: const batch = db.batch() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: A write batch that applies all queued operations atomically when flushed. (GitHub)
  • Example: const batch = db.batch()

Use batches when you need grouped writes or lower overhead for many updates.

await batch.put(key, [value], [options])

API definition on GitHub

  • Signature: await batch.put(key, [value], [options]) (GitHub)
  • Parameters: Same arguments and cas behavior as db.put(...). (GitHub)
  • Returns: Resolves after queuing the write inside the batch. (GitHub)
  • Example: await batch.put('settings', { retries: 3 })

const entry = await batch.get(key)

API definition on GitHub

  • Signature: const entry = await batch.get(key) (GitHub)
  • Parameters: key uses the batch's key encoding. (GitHub)
  • Returns: The pending or committed entry visible within the batch, or null when missing. (GitHub)
  • Example: const entry = await batch.get('settings')

await batch.del(key, [options])

API definition on GitHub

  • Signature: await batch.del(key, [options]) (GitHub)
  • Parameters: Same arguments and cas behavior as db.del(...). (GitHub)
  • Returns: Resolves after queuing the delete inside the batch. (GitHub)
  • Example: await batch.del('settings')

await batch.flush()

API definition on GitHub

  • Signature: await batch.flush() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves after committing the queued operations and releasing the batch lock. (GitHub)
  • Example: await batch.flush()

await batch.close()

API definition on GitHub

  • Signature: await batch.close() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves after discarding the batch and releasing any lock it holds. (GitHub)
  • Example: await batch.close()

Call batch.close() when you want to abort a batch without writing it.

Reads and iteration

const entry = await db.get(key)

API definition on GitHub

  • Signature: const entry = await db.get(key) (GitHub)
  • Parameters: key uses keyEncoding. (GitHub)
  • Returns: null when the key is missing, otherwise { seq, key, value }, where seq is the backing Hypercore block index. (GitHub)
  • Example: const entry = await db.get('config')

const entry = await db.getBySeq(seq, [options])

API definition on GitHub

  • Signature: const entry = await db.getBySeq(seq, [options]) (GitHub)
  • Parameters: seq is a Hypercore block index; options pass through to the underlying core lookup. (GitHub)
  • Returns: null when the block does not exist, otherwise the decoded { key, value } entry stored at that sequence number. (GitHub)
  • Example: const entry = await db.getBySeq(4)

const stream = db.createReadStream([range], [options])

API definition on GitHub

  • Signature: const stream = db.createReadStream([range], [options]) (GitHub)
  • Parameters: range can include gt, gte, lt, or lte; options.reverse flips sort order and options.limit caps the number of yielded entries. (GitHub)
  • Returns: An async iterable of { seq, key, value } entries sorted by encoded key order. (GitHub)
  • Example: for await (const entry of db.createReadStream({ gte: 'a', lt: 'd' })) {}

const entry = await db.peek([range], [options])

API definition on GitHub

  • Signature: const entry = await db.peek([range], [options]) (GitHub)
  • Parameters: Accepts the same range and options as db.createReadStream(...). (GitHub)
  • Returns: The first matching entry, or null if the range is empty. (GitHub)
  • Example: const first = await db.peek({ gte: 'user:' })

History and change tracking

const stream = db.createHistoryStream([options])

API definition on GitHub

  • Signature: const stream = db.createHistoryStream([options]) (GitHub)
  • Parameters: options.live keeps the stream open; options.reverse yields newest first; gte, gt, lte, and lt bound the sequence range; limit caps results. Negative sequence bounds are resolved relative to the current version. (GitHub)
  • Returns: An async iterable of change records shaped like { type, seq, key, value }, where type is 'put' or 'del'. (GitHub)
  • Example: for await (const entry of db.createHistoryStream({ reverse: true, limit: 1 })) {}

const stream = db.createDiffStream(otherVersion, [options])

API definition on GitHub

  • Signature: const stream = db.createDiffStream(otherVersion, [options]) (GitHub)
  • Parameters: otherVersion is the version to compare against; options match db.createReadStream(...) except reverse is not supported. (GitHub)
  • Returns: An async iterable of { left, right } pairs sorted by key, where each side is an entry or null when that side lacks the key. (GitHub)
  • Example: for await (const diff of db.createDiffStream(previousVersion)) {}

Causally equal entries are omitted from the diff, so the stream only yields actual changes between versions.

const entryWatcher = await db.getAndWatch(key, [options])

API definition on GitHub

  • Signature: const entryWatcher = await db.getAndWatch(key, [options]) (GitHub)
  • Parameters: key selects one entry; options.keyEncoding and options.valueEncoding can override the bee defaults for the watched node. (GitHub)
  • Returns: A watcher whose node property always contains the latest entry for that key. (GitHub)
  • Example: const entryWatcher = await db.getAndWatch('config')

Listen to entryWatcher.on('update') when you need push-style notifications for a single key.

await entryWatcher.close()

API definition on GitHub

  • Signature: await entryWatcher.close() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves after stopping the watcher created by db.getAndWatch(...). (GitHub)
  • Example: await entryWatcher.close()

const watcher = db.watch([range])

API definition on GitHub

  • Signature: const watcher = db.watch([range]) (GitHub)
  • Parameters: range accepts the same bounds as db.createReadStream(...), except reverse; keyEncoding and valueEncoding can override the yielded snapshot encodings. (GitHub)
  • Returns: An async iterable watcher that yields [current, previous] snapshot pairs each time the watched range changes. (GitHub)
  • Example: for await (const [current, previous] of db.watch({ gte: 'user:' })) {}

Watchers are not supported on subs or checkouts. Use range to narrow the scope on the root bee instead.

await watcher.ready()

API definition on GitHub

  • Signature: await watcher.ready() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves when a range watcher has loaded and is actively tracking changes. (GitHub)
  • Example: await watcher.ready()

await watcher.close()

API definition on GitHub

  • Signature: await watcher.close() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves after stopping the range watcher. Breaking out of the async iterator also stops it. (GitHub)
  • Example: await watcher.close()

Snapshots and sub-bees

const snapshot = db.checkout(version)

API definition on GitHub

  • Signature: const snapshot = db.checkout(version) (GitHub)
  • Parameters: version is the modification count to read from. (GitHub)
  • Returns: A read-only Hyperbee view pinned to that version. (GitHub)
  • Example: const beforeImport = db.checkout(10)

const snapshot = db.snapshot()

API definition on GitHub

  • Signature: const snapshot = db.snapshot() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: A read-only checkout pinned to the current db.version. (GitHub)
  • Example: const current = db.snapshot()

const sub = db.sub(prefix, [options])

API definition on GitHub

  • Signature: const sub = db.sub(prefix, [options]) (GitHub)
  • Parameters: prefix becomes the namespace prefix; options.sep sets the separator buffer; options.keyEncoding and options.valueEncoding can override the parent encodings for the sub-bee. (GitHub)
  • Returns: A new Hyperbee view that transparently prefixes all keys in that namespace. (GitHub)
  • Example: const users = db.sub('users')

Sub-bees are useful when one Hyperbee needs multiple logical keyspaces without creating extra cores.

const header = await db.getHeader([options])

API definition on GitHub

  • Signature: const header = await db.getHeader([options]) (GitHub)
  • Parameters: options are passed through to the underlying core.get(...) call. (GitHub)
  • Returns: The decoded header stored in the first block, or throws when the header cannot be decoded. (GitHub)
  • Example: const header = await db.getHeader()

Replication and lifecycle

const stream = db.replicate(isInitiatorOrStream)

API definition on GitHub

  • Signature: const stream = db.replicate(isInitiatorOrStream) (GitHub)
  • Parameters: Pass the same initiator flag or replication stream you would pass to the underlying Hypercore replication API. (GitHub)
  • Returns: The replication stream for the backing core. (GitHub)
  • Example: const replicationStream = db.replicate(true)

In larger apps, replication is often handled through a shared Corestore rather than per-bee streams.

await db.close()

API definition on GitHub

  • Signature: await db.close() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Resolves after closing the bee and its backing core. (GitHub)
  • Example: await db.close()

Static helpers

const isHyperbee = await Hyperbee.isHyperbee(core, [options])

API definition on GitHub

  • Signature: const isHyperbee = await Hyperbee.isHyperbee(core, [options]) (GitHub)
  • Parameters: core is the candidate Hypercore; options pass through to the first-block lookup. (GitHub)
  • Returns: true when the core contains a Hyperbee header, otherwise false. (GitHub)
  • Example: const ok = await Hyperbee.isHyperbee(core)

See also

On this page