# Release Overview



A curated record of changes across P2P's building blocks and helpers, newest first. For the raw upstream record, see each module's GitHub releases; this page is the docs-team view of what the changes mean for your application.

<Callout type="info">
  Looking for `pear` CLI or `pear-*` module releases instead? See [Pear's release overview](/pear/release-overview). For Bare's releases, see [Bare's release overview](/bare/release-overview).
</Callout>

## 2026-10-15 — P2P module updates [#2026-10-15--p2p-module-updates]

The module releases that [Pear 3.6.0](/pear/release-overview) bundles. An application pins its own copies in its `package.json`, so upgrade these dependencies directly to pick the changes up.

### Hypercore — v11.38.0, v11.37.2, v11.37.0 [#hypercore--v11380-v11372-v11370]

* Added (v11.38.0): [`core.count(start, end)`](/p2p/reference/building-blocks/hypercore#await-corecountstart-end) returns how many blocks in `[start, end)` the core has stored locally. [`core.has(start, end)`](/p2p/reference/building-blocks/hypercore#await-corehasstart-end) is `true` exactly when the count is `end - start`.
* Fixed (v11.37.2): [`core.clear()`](/p2p/reference/building-blocks/hypercore#await-coreclearstart-end-options) deleted the tree nodes of still-stored blocks to the left of the cleared range (since v11.16.0), so a peer requesting one of those blocks failed with `INVALID_OPERATION: Expected tree node N from storage, got (nil)`. For example, after `clear(1)` a fresh peer could not read block 0. [`drive.clear()`](/p2p/reference/building-blocks/hyperdrive#await-driveclearpath-options) goes through it. Upgrading does not restore nodes that an earlier `clear()` already deleted.
* Changed (v11.37.0): [manifest decoding](/p2p/reference/building-blocks/hypercore#new-hypercorestorage-key-options) accepts `version` 3, which is wire-compatible with version 2. Earlier releases throw `Unknown version: 3` on such a manifest, and versions above 3 are still rejected.

### Hyperdrive — v13.3.4 [#hyperdrive--v1334]

* Fixed: [`drive.downloadDiff()`](/p2p/reference/building-blocks/hyperdrive#await-drivedownloaddiffversion-folder-options) finished without fetching the data blocks of entries written with `dedup: true`. It downloaded each entry's contiguous range, which for those entries covers only the block map. It now follows the map, as [`drive.download()`](/p2p/reference/building-blocks/hyperdrive#drivedownloadfolder-options) has since v13.3.3.
* Fixed: [`download.destroy()`](/p2p/reference/building-blocks/hyperdrive#download) no longer waits for the blobs core to open before closing, and closing the drive during a download resolves `download.done()` instead of rejecting with `REQUEST_CANCELLED`. This covers the `Download` that `drive.download()` and `drive.downloadDiff()` return.

### HyperDHT — v6.34.1 [#hyperdht--v6341]

* Fixed: a server that relays a connection now notices when the relay is lost, before or after pairing. It releases the unconnected stream and its hole puncher once no direct connection has taken over within the grace period and no hole punch is still running. Previously a punch parked after `TRY_LATER`, or a relay that died after pairing, could hold them until another close event, such as keep-alive, cleaned up.
* Added: a [`relayRecoveryWait`](/p2p/reference/building-blocks/hyperdht#createserveroptions) option to [`node.createServer()`](/p2p/reference/building-blocks/hyperdht#nodecreateserveroptions-onconnection), in milliseconds and `30000` by default, that sets that grace period.

### Hyperswarm — v4.17.2 [#hyperswarm--v4172]

* Changed: a DHT `network-update` event now triggers the swarm's network-change handling—a keep-alive on every connection and a refresh of every topic—only when the DHT has just come back online. Before, every `network-update` that arrived while the DHT was online triggered it. A `network-change` event still triggers it as before.

### Compact-encoding — v3.5.2 [#compact-encoding--v352]

* Changed: decoding [`cenc.arraybuffer`](/p2p/reference/helpers/compact-encoding#cencarraybuffer) or a [`cenc.frame(enc)`](/p2p/reference/helpers/compact-encoding#cencframeenc) frame whose declared length is longer than the bytes left now throws `Out of bounds`. Before, `arraybuffer` returned a zero-padded `ArrayBuffer` and `frame` decoded whatever bytes remained.

### Corestore — v7.13.0, v7.12.6 [#corestore--v7130-v7126]

* Added (v7.13.0): an [`alwaysLatestBlock`](/p2p/reference/helpers/corestore#storealwayslatestblock) constructor option, `false` by default, that turns on [`allowLatestBlock`](/p2p/reference/building-blocks/hypercore#hypercoreoptions) for every core the store opens. Sessions and namespaces created from the store inherit it, and an `allowLatestBlock` passed to [`store.get()`](/p2p/reference/helpers/corestore#storegetkey---name-a-name-hypercoreopts) takes precedence.
* Added (v7.12.6): `store.get()` accepts [`manifestVersion`](/p2p/reference/helpers/corestore#storegetkey---name-a-name-hypercoreopts), which overrides [`store.manifestVersion`](/p2p/reference/helpers/corestore#storemanifestversion) for the manifest of a new writable core. A core that already exists under that name keeps the version it was created with.

### Protomux — v3.13.0, v3.12.1 [#protomux--v3130-v3121]

* Added (v3.13.0): [`mux.watch()`](/p2p/reference/helpers/protomux#muxwatch-protocol-id--callback), [`mux.unwatch()`](/p2p/reference/helpers/protomux#muxunwatch-protocol-id--callback), and [`mux.unwatchAll()`](/p2p/reference/helpers/protomux#muxunwatchall-protocol-id-) observe channels opening for a protocol, and optionally an id, without pairing them. Any number of watchers can share a protocol. A watcher that throws, or returns a promise that rejects, emits a `warning` on the stream and leaves the channel open.
* Fixed (v3.12.1): a batched message whose declared length runs past the end of the batch now fails with `Out of bounds`. It failed with `uint must be between 0 and 9007199254740991, use biguint` before.

### Hyperschema — v1.26.2, v1.26.0, v1.25.0 [#hyperschema--v1262-v1260-v1250]

* Changed (v1.25.0): versioned types have a [`framed`](/p2p/reference/helpers/hyperschema#versioned-type) option. A new versioned type defaults to `framed: true`, which length-prefixes each of its version structs unless the struct is `compact`, so a decoder from an earlier schema generation can skip fields that a later generation appended. A type already in your `schema.json` keeps its unframed layout (the next build records `framed: false`), and setting `framed: true` on it changes the bytes it writes. Keep the previous `schema.json` when you regenerate: without it every versioned type is framed, which differs from the layout of a spec generated with v1.24.0 or earlier.
* Fixed (v1.26.0): a [`uint1`–`uint7`](/p2p/reference/helpers/hyperschema#built-in-types) field decoded as `true` or `false` instead of its value in code generated with v1.23.0 through v1.25.0. The bytes written were correct, so regenerating the spec with v1.26.0 or later is enough, and stored data needs no migration.
* Added (v1.26.0): a [`constant`](/p2p/reference/helpers/hyperschema#fields) field option—a `bool`, integer, `string` or `null` literal that the decoder always returns for the field. A constant is never encoded, takes no flag bit and does not bump the schema version. It cannot be combined with `required`, `array`, `record` or `inline`.

See the [Hyperschema reference](/p2p/reference/helpers/hyperschema) for the full API, and [RPC and schemas](/bare/explanation/rpc-and-schemas) for where it fits.

### blind-peering — v2.10.1, v2.10.0, v2.9.1 [#blind-peering--v2101-v2100-v291]

* Changed (v2.9.1): [`sendNotification()`](/p2p/reference/helpers/blind-peering#await-blindsendnotificationcore-opts) picks a random connected blind peer among the `pick` closest to `target` (2 by default), rather than the closest connected one, to spread notification load.
* Added (v2.10.0): a [`client`](/p2p/reference/helpers/blind-peering#blindpeeringoptions) constructor option, `{ name, version }`, that identifies your application to blind peers. Both values are sent in the connection handshake, along with the blind-peering version.
* Added (v2.10.1): a [`skipConnectionMetadata`](/p2p/reference/helpers/blind-peering#blindpeeringoptions) constructor option, `false` by default. When `true`, the handshake carries no metadata at all—neither `client` nor the blind-peering version.

### blind-peer — v3.16.0, v3.15.1 [#blind-peer--v3160-v3151]

* Added (v3.16.0): the blind peer answers `add-cores` and notification requests that a client sends with `requestAddCores()` and `requestSendNotification()` from `blind-peer-muxer` v1.7.0, which builds on the new `protomux-request` v0.1.0. An `add-cores` response lists each core's `key`, the `length` the blind peer held, and whether the request `activated` it. [blind-peering](/p2p/reference/helpers/blind-peering) 2.10.1 still sends one-way messages, so it gets no response. See [Responses](/p2p/reference/helpers/blind-peer#responses).
* Changed (v3.16.0): a request over [`perReferrerRateLimitParams`](/p2p/reference/helpers/blind-peer#blindpeeroptions) now raises a `RATE_LIMITED` error. It emits `muxer-error` and counts in `stats.muxerErrors`, in addition to the `per-referrer-rate-limited` event it already emitted. A client that sent the request with `requestAddCores()` gets the error as a rejection. A client that sent it as a one-way message, as blind-peering does, sees no difference.
* Changed: the [Corestore](/p2p/reference/helpers/corestore) that [blind-peer](/p2p/reference/helpers/blind-peer) creates when you do not pass a [`store`](/p2p/reference/helpers/blind-peer#blindpeeroptions) is opened with `alwaysLatestBlock: true` (added in v7.13.0, above), so its replicator includes a request for the latest block in every upgrade request. A `store` you pass in is used as given. [`pear blind-peer start`](/pear/reference/pear/cli#pear-blind-peer) passes none, so it gets the new behaviour.

## 2026-09-22 — P2P module updates [#2026-09-22--p2p-module-updates]

The module releases that [Pear 3.5.0](/pear/release-overview) bundles. An application pins its own copies in its `package.json`, so upgrade these dependencies directly to pick the changes up.

### Hypercore — v11.36.1, v11.36.0, v11.35.4 [#hypercore--v11361-v11360-v11354]

* Added (v11.36.0): [`await core.setAlwaysLatestBlock(enabled)`](/p2p/reference/building-blocks/hypercore#await-coresetalwayslatestblockenabled).
* Changed (v11.35.4): a session opened with a [`group`](/p2p/reference/building-blocks/hypercore#new-hypercorestorage-key-options) option assigns that group to a core that has none, so a core first opened without a group can join one later. Previously the option only took effect when the core was created.

### HyperDHT — v6.34.0 [#hyperdht--v6340]

* Changed: [`node.stats`](/p2p/reference/building-blocks/hyperdht#nodestats) reports more counters—`punches.tryLater` and `punches.tryLaterRelayedHandshakesAtLeastOnce` for rate-limited hole-punch attempts, and a `socketPool` group for socket pool lifecycle. The existing `punches` and `relaying` counters are unchanged.

### Hyperswarm — v4.17.1 [#hyperswarm--v4171]

* Changed: a client connection that fails with `CANNOT_HOLEPUNCH` is now retried through [`relayThrough`](/p2p/reference/building-blocks/hyperswarm#new-hyperswarmopts--), joining `HOLEPUNCH_ABORTED`, `HOLEPUNCH_DOUBLE_RANDOMIZED_NATS` and `REMOTE_NOT_HOLEPUNCHABLE`. For Pear this means a relay registered with [`--relay`](/pear/reference/pear/cli#relay-flag) is also used when the DHT reports that a hole punch cannot succeed.

### Compact-encoding — v3.5.0, v3.4.0 [#compact-encoding--v350-v340]

* Added (v3.5.0): [`cenc.fixed8`, `cenc.fixed16` and `cenc.fixed24`](/p2p/reference/helpers/compact-encoding#cencfixed64), alongside the existing `fixed32` and `fixed64`.
* Added (v3.4.0): [`cenc.bitarray`](/p2p/reference/helpers/compact-encoding#cencbitarray).

### Corestore — v7.12.5, v7.12.3 [#corestore--v7125-v7123]

* Changed (v7.12.5): [`store.get()`](/p2p/reference/helpers/corestore#storegetkey---name-a-name-hypercoreopts) forwards `allowLatestBlock` to the Hypercore it returns, so the option can be set per session through the store rather than only on a directly constructed core.
* Fixed (v7.12.3): `store.get({ group })` on a core that is already open without a group now assigns it, so the core reaches [`store.notifyGroup(topic)`](/p2p/reference/helpers/corestore#storenotifygrouptopic). The assignment moved into Hypercore (v11.35.4, above).

### Protomux — v3.12.0 [#protomux--v3120]

* Changed: an async channel handler (`onmessage`, `onopen`, `onclose`, `ondrain`, `ondestroy`) whose returned promise rejects **after its channel has closed** now makes the underlying stream emit a [`warning`](/p2p/reference/helpers/protomux#channelondrain) event carrying the error, instead of destroying the stream. A rejection while the channel is still open still destroys the stream, and a synchronous throw is unaffected. Listen for `warning` if you relied on the old behaviour to surface post-close errors.

### Secretstream — v6.9.2 [#secretstream--v692]

* Added: a [`filterZeroByteMessages`](/p2p/reference/helpers/secretstream#secretstreamoptions) option, which drops zero-byte messages before they reach the message handler. It is on implicitly whenever `keepAlive` is set—so keep-alive users already had this behaviour—and can now be enabled on its own.

### Hyperschema — v1.24.0, v1.23.0 [#hyperschema--v1240-v1230]

* **Breaking (wire format, v1.23.0):** a field with `array: true` and type `bool` is packed into a bitfield—a `uint` length followed by `ceil(length / 8)` bytes—instead of one byte per value. A spec regenerated with 1.23.0 or later cannot decode bool arrays written by a spec generated with 1.22.x or earlier, and the reverse. Check any schema with a bool array before regenerating, and migrate data already written in the old layout.
* Changed (v1.23.0): the bitwise types `uint1`–`uint7` used as an array now fail at build time with `cannot be used as an array`; they only exist inside a struct's flags byte.
* Added (v1.24.0): `fixed8`, `fixed16` and `fixed24` types, backed by the new compact-encoding codecs.

See the [Hyperschema reference](/p2p/reference/helpers/hyperschema) for the full API, and [RPC and schemas](/bare/explanation/rpc-and-schemas) for where it fits.

### blind-peering — v2.9.0, v2.8.0 [#blind-peering--v290-v280]

* Changed (v2.8.0): `sendNotification()` is rate-limited by default—10 per second, each waiting up to 10 seconds for a slot. Tune it with the new `notificationRateLimit` constructor option (`{ capacity, interval, timeout }`), or pass `null` to disable it.
* Changed (v2.9.0): `addAutobase()` finds every view and writer core through the Autobase itself, so its `additionalViews` option is ignored. Register cores that are not part of the Autobase with `addCore()` instead.
* Added (v2.9.0): `addAutobase()` accepts an Autobee.

### blind-peer — v3.15.0, v3.14.0 [#blind-peer--v3150-v3140]

* Added: constructor options [`perReferrerRateLimitParams`](/p2p/reference/helpers/blind-peer#blindpeeroptions) (v3.15.0), a per-referrer rate limit on `add-cores` requests, and [`notificationErrorSnapshotDelay`](/p2p/reference/helpers/blind-peer#blindpeeroptions) (v3.14.0).
* Changed (v3.15.0): the default `notificationTimeout` rises from 10 to 30 seconds.

## 2026-08-24 — P2P module updates [#2026-08-24--p2p-module-updates]

### Hypercore — v11.35.2, v11.35.1, v11.35.0 [#hypercore--v11352-v11351-v11350]

* Added (v11.35.0): [`core.getManifest([options])`](/p2p/reference/building-blocks/hypercore#coregetmanifestoptions) returns the manifest, optionally in its encoded wire form via `options.raw`.
* Added (v11.35.0): [`Hypercore.parseManifest(manifest, [key])`](/p2p/reference/building-blocks/hypercore#hypercoreparsemanifestmanifest-key) decodes and validates a manifest, optionally checking it hashes to a given key.
* Changed (v11.35.0): the [`manifest`](/p2p/reference/building-blocks/hypercore#new-hypercorestorage-key-options) option accepts an encoded manifest Buffer—a Buffer is read as a public key only when it is exactly 32 bytes.
* Fixed (v11.35.1): the idle range completion scan.
* Fixed (v11.35.2): the replicator bails out when the core is closing, instead of continuing work against a closing session.

### HyperDHT — v6.33.2, v6.33.1 [#hyperdht--v6332-v6331]

* Fixed (v6.33.1): a node was pushed twice during HyperDHT initialization.
* Fixed (v6.33.1): the clearing timeout is unreferenced, so it no longer holds the process open.
* Fixed (v6.33.2): handshakes received while suspended are cleaned up, and clearing is reordered to match.

### Compact-encoding — v3.3.2, v3.3.1 [#compact-encoding--v332-v331]

* Added (v3.3.2): TypeScript typings.
* Added (v3.3.1): validation on the signed integer codecs, so out-of-range values are rejected rather than silently encoded.

## 2026-07-30 — P2P module updates [#2026-07-30--p2p-module-updates]

### Hypercore — v11.34.0–v11.35.1 [#hypercore--v11340v11351]

* Changed (v11.34.0): the tree-node proof cache is enabled, cutting repeated proof work for peers that serve many connections.
* Added (v11.35.0): a manifest can be supplied as a raw buffer.
* Fixed (v11.35.1): the idle range-completion scan.
* Fixed (v11.34.1): the latest batch is always selected.

### Hyperdrive — v13.3.3 [#hyperdrive--v1333]

* Fixed: [`drive.download()`](/p2p/reference/building-blocks/hyperdrive#drivedownloadfolder-options) and [`drive.has()`](/p2p/reference/building-blocks/hyperdrive) silently stalled or fetched the wrong data for entries written with `dedup: true`. Those entries store blobs as a non-contiguous block map rather than a contiguous range, and the contiguous form was being used for every entry. `downloadDiff()` had the same bug, and this release did not fix it: v13.3.4 did (see the 2026-10-07 entry).

### HyperDHT — v6.33.0 [#hyperdht--v6330]

* Fixed: relayed server connections now inherit `connectionKeepAlive` the way direct sockets already did, and a relay-to-direct upgrade sends an explicit handoff packet so the peer observes the direct path before the relay is torn down.
* Fixed: a LAN shortcut no longer blocks hole-punch fallback, and relay sockets close once a direct connection is established.
* Removed: the internal `global.Pear` reference, following the Pear v3 removal of the ambient Pear API.

### Corestore — v7.12.0, v7.11.1 [#corestore--v7120-v7111]

* Changed (v7.12.0): `suspend()` no longer performs an implicit flush. Write-ahead-log filtering makes reopening cheap, so the flush is no longer needed on every suspend.
* Added (v7.11.1): a `treeCache` option for tuning Hypercore's tree-node cache—raise `maxSize` on peers that serve more connections than usual.

## See also [#see-also]

* [Pear's release overview](/pear/release-overview)—`pear` CLI and `pear-*` module releases.
* [Bare's release overview](/bare/release-overview)—Bare runtime and bare-\* module releases.
* [Building blocks reference](/p2p/reference/building-blocks/hypercore)—current API for Hypercore, Hyperdrive, and other building blocks.
* [Helpers reference](/p2p/reference/helpers/corestore)—current API for Corestore.
