Pp2pbuilders
learn › Holepunch walkthroughs

7 min read · also at #/learn/hp-hyperbee

Hyperbee: a database on a log

Hyperbee is a B-tree encoded as
Hypercore blocks: each put appends a node describing the tree change. The
result is a sorted key/value database with the replication properties of a
log
— single writer, many verified readers, sparse download.

const Hypercore = require('hypercore')
const Hyperbee = require('hyperbee')

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

await bee.put('profile!alice', { nick: 'alice' })
const node = await bee.get('profile!alice')     // { key, value } or null
await bee.del('profile!alice')

The idiom: key ranges are your tables

There are no tables or secondary indexes — you design your keyspace so
ordered scans answer your queries:

post!front!new!<invertedTs>!<id>   → post ref
comment!<postId>!<ts>!<id>         → comment ref
vote!<targetId>!<voter>            → direction

Then a prefix scan is a query:

for await (const { key, value } of bee.createReadStream({
  gt: 'comment!abc!', lt: 'comment!abc!~'
})) { /* every comment on post abc, in time order */ }

Trick worth stealing: inverted timestamps (999…9 - ms) make ascending
scans return newest-first, so "latest 50 posts" is a limited range read.

Two ways to use it

  1. Replicated bee — the author writes, readers replicate and query

sparsely (a reader checking one key downloads ~log(n) blocks).

  1. Local index — a private bee as your app's query layer. This is

p2pbuilders: the indexer folds every followed Hypercore into a local
Hyperbee (post!…, vote!…, rep!…), and the UI only ever queries
the bee. Rebuildable state, ordered queries, no SQL dependency.

« Hypercore: the signed append-only log Hyperdrive: a filesystem on two cores »