# Hypercore



<Status level="stable" />

Hypercore is a secure, distributed append-only log for sharing large datasets and realtime streams. It supports sparse replication, verified reads, optional block encryption, and session-based workflows for building higher-level local-first and peer-to-peer data structures.

<Callout type="info">
  For how Hypercore relates to Hyperblobs and [Hyperdrive](/p2p/reference/building-blocks/hyperdrive), see [From append-only logs to files](/p2p/explanation/from-logs-to-files).
</Callout>

## Install [#install]

```sh
npm i hypercore
```

## Quickstart [#quickstart]

```js
import Hypercore from 'hypercore'

const core = new Hypercore('./my-first-core', { valueEncoding: 'utf-8' })
await core.ready()

await core.append('hello')
await core.append('from hypercore')

console.log('length:', core.length)
console.log('first block:', await core.get(0))
console.log('second block:', await core.get(1))

for await (const block of core.createReadStream()) {
  console.log('streamed:', block)
}

await core.close()
```

## API Reference [#api-reference]

### Constructors and sessions [#constructors-and-sessions]

#### `new Hypercore(storage, [key], [options])` [#new-hypercorestorage-key-options]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L48)

Make a new Hypercore instance.

| Parameter | Type                                                                | Description                                                                                                                    |
| --------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `storage` | `string\|object`                                                    | should be set to a directory where you want to store the data and core metadata.                                               |
| `key`     | [`Buffer\|string`](https://nodejs.org/api/buffer.html#class-buffer) | can be set to a Hypercore key which is a hash of Hypercore's internal auth manifest, describing how to validate the Hypercore. |
| `options` | [`HypercoreOptions`](#hypercoreoptions)                             | —                                                                                                                              |

| Option                 | Default     | Description                                                                                                                                                                                                                                                                                                                                        |
| ---------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createIfMissing`      | `true`      | create a new Hypercore key pair if none was present in storage                                                                                                                                                                                                                                                                                     |
| `overwrite`            | `false`     | overwrite any old Hypercore that might already exist                                                                                                                                                                                                                                                                                               |
| `force`                | `false`     | Advanced option. Will force overwrite even if the header's key & the passed key don't match                                                                                                                                                                                                                                                        |
| `valueEncoding`        | —           | defaults to binary                                                                                                                                                                                                                                                                                                                                 |
| `encodeBatch`          | —           | optionally apply an encoding to complete batches                                                                                                                                                                                                                                                                                                   |
| `keyPair`              | `kp`        | optionally pass the public key and secret key as a key pair                                                                                                                                                                                                                                                                                        |
| `encryption`           | —           | the block encryption key                                                                                                                                                                                                                                                                                                                           |
| `onwait`               | —           | hook that is called if gets are waiting for download                                                                                                                                                                                                                                                                                               |
| `timeout`              | `0`         | wait at max some milliseconds (0 means no timeout)                                                                                                                                                                                                                                                                                                 |
| `writable`             | `true`      | disable appends and truncates                                                                                                                                                                                                                                                                                                                      |
| `inflightRange`        | `null`      | Advanced option. Set to \[minInflight, maxInflight] to change the min and max inflight blocks per peer when downloading.                                                                                                                                                                                                                           |
| `ongc`                 | —           | A callback called when the session is garbage collected                                                                                                                                                                                                                                                                                            |
| `onseq`                | —           | A callback called when core.get(index) is called.                                                                                                                                                                                                                                                                                                  |
| `notDownloadingLinger` | `20000`     | How many milliseconds to wait after downloading finishes keeping the connection open. Defaults to a random number between 20-40s                                                                                                                                                                                                                   |
| `allowFork`            | `true`      | Enables updating core when it forks                                                                                                                                                                                                                                                                                                                |
| `allowLatestBlock`     | `false`     | Request latest block when requesting upgrade                                                                                                                                                                                                                                                                                                       |
| `group`                | —           | Advanced option. A 32-byte group topic to assign the core to, which Corestore's [`store.notifyGroup(topic)`](/p2p/reference/helpers/corestore#storenotifygrouptopic) watches. Only applied if the core has no group yet; from v11.35.4 that includes a new session on an already-open core. See [`core.setGroup(topic)`](#await-coresetgrouptopic) |
| `userData`             | —           | An object to assign to the local User Data storage                                                                                                                                                                                                                                                                                                 |
| `manifest`             | `undefined` | Advanced option. Set the manifest when creating the hypercore. See Manifest section for more info                                                                                                                                                                                                                                                  |
| `preload`              | `undefined` | Advanced option. A promise that returns constructor options overrides before the core is opened                                                                                                                                                                                                                                                    |
| `storage`              | `undefined` | An alternative to passing storage as a dedicated argument                                                                                                                                                                                                                                                                                          |
| `key`                  | `null`      | An alternative to passing key as a dedicated argument                                                                                                                                                                                                                                                                                              |

```js
const core = new Hypercore('./directory') // store data in ./directory
```

User Data is a local-only key/value store with string keys and string or `Buffer` values. It is not replicated and is useful for peer-specific metadata such as encryption keys or app state.

The manifest controls how a core is authenticated, including `version`, `hash`, `quorum`, `signers`, `prologue`, `linked`, and manifest-level `userData`. Changing the manifest changes the resulting Hypercore key. Decoding accepts manifest `version` 1 to 3, plus the legacy `0` form. Version 3 has the same layout as version 2 and is accepted from v11.37.0. Earlier releases throw `Unknown version: 3` when they read a core whose manifest uses it.

#### `core.session([options])` [#coresessionoptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L238)

Creates a new Hypercore instance that shares the same underlying core.

| Parameter | Type                                | Default | Description                                                             |
| --------- | ----------------------------------- | ------- | ----------------------------------------------------------------------- |
| `options` | [`SessionOptions`](#sessionoptions) | `{}`    | Options are inherited from the parent instance, unless they are re-set. |

* Returns: [`Hypercore`](/p2p/reference/building-blocks/hypercore) — A new Hypercore session sharing the same underlying storage.
* Throws: `SESSION_CLOSED` if called on a core that is already closing.

```js
const core = new Hypercore('./atom-example')
await core.ready()

await core.append('block 1')

const atom = core.state.storage.createAtom()
const atomicSession = core.session({ atom })

await core.append('block 2') // Add blocks not using the atom

await atomicSession.append('atom block 2') // Add different block to atom
await atom.flush()

console.log((await core.get(core.length - 1)).toString()) // prints 'atom block 2' not 'block 2'
```

#### `await core.commit(session, opts = {})` [#await-corecommitsession-opts--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L587)

Attempt to apply blocks from the session to the `core`. `core` must be a default core, aka a non-named session.

| Parameter | Type                                                    | Default | Description                                                        |
| --------- | ------------------------------------------------------- | ------- | ------------------------------------------------------------------ |
| `session` | [`Hypercore`](/p2p/reference/building-blocks/hypercore) | —       | The named or atom session whose staged blocks should be committed. |
| `opts`    | [`CommitOptions`](#commitoptions)                       | `{}`    | —                                                                  |

* Returns: [`Promise<{length: number, byteLength: number}\|null>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — `null` if committing failed.
* Throws: `INVALID_OPERATION` if no database batch was passed, or the tree changed during the batch.

| Option       | Default     | Description                                                   |
| ------------ | ----------- | ------------------------------------------------------------- |
| `length`     | —           | the core's length after committing the blocks                 |
| `treeLength` | —           | The expected length of the core's merkle tree prior to commit |
| `keyPair`    | —           | The keypair to use when committing                            |
| `signature`  | `undefined` | The signature for the blocks being committed                  |

#### `core.snapshot([options])` [#coresnapshotoptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L230)

Same as [`core.session(options)`](#coresessionoptions), but backed by a storage snapshot so will not truncate nor append.

| Parameter | Type                                | Description                                                                    |
| --------- | ----------------------------------- | ------------------------------------------------------------------------------ |
| `options` | [`SessionOptions`](#sessionoptions) | Options forwarded to `core.session()` with `snapshot: true` set automatically. |

* Returns: [`Hypercore`](/p2p/reference/building-blocks/hypercore) — A new read-only Hypercore session locked to the current length.

```js
const snap = core.snapshot()
console.log(snap.length) // frozen at the moment snapshot() was called
```

### Writing and local mutation [#writing-and-local-mutation]

#### `await core.append(block, options = {})` [#await-coreappendblock-options--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1149)

Append a block of data (or an array of blocks) to the core. Returns the new length and byte length of the core.

| Parameter | Type                                                                       | Default | Description                                       |
| --------- | -------------------------------------------------------------------------- | ------- | ------------------------------------------------- |
| `block`   | [`Buffer\|Array<Buffer>`](https://nodejs.org/api/buffer.html#class-buffer) | —       | A single block, or an array of blocks, to append. |
| `options` | [`AppendOptions`](#appendoptions)                                          | `{}`    | —                                                 |

* Returns: [`Promise<{length: number, byteLength: number}>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — The new `length` and `byteLength` of the core after appending.
* Throws:
  * `SESSION_CLOSED` if the core has been closed.
  * `SESSION_NOT_WRITABLE` if the core is not writable.
  * `INVALID_OPERATION` if the append is inconsistent with the manifest prologue.
  * `BAD_ARGUMENT` if an appended block exceeds the maximum suggested block size.

| Option      | Default     | Description                                                                 |
| ----------- | ----------- | --------------------------------------------------------------------------- |
| `writable`  | `false`     | Enabled ignores writable check. Does not override whether core is writable. |
| `maxLength` | `undefined` | The maximum resulting length of the core after appending                    |
| `keyPair`   | —           | KeyPair used to sign the blocks                                             |
| `signature` | `null`      | Set signature for blocks                                                    |

```js
// simple call append with a new block of data
await core.append(Buffer.from('I am a block of data'))

// pass an array to append multiple blocks as a batch
await core.append([Buffer.from('batch block 1'), Buffer.from('batch block 2')])
```

#### `core.createWriteStream()` [#corecreatewritestream]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1105)

Make a write stream to append chunks as blocks.

* Returns: `object` — A Writable stream; each chunk written becomes one block appended to the core.

```js
const ws = core.createWriteStream()

// Listen for stream finishing
const done = new Promise((resolve) => ws.on('finish', resolve))

for (const data of ['hello', 'world']) ws.write(data)
ws.end()

await done

console.log(await core.get(core.length - 2)) // 'hello'
console.log(await core.get(core.length - 1)) // 'world'
```

#### `await core.clear(start, [end], [options])` [#await-coreclearstart-end-options]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L932)

Clear stored blocks between `start` and `end`, reclaiming storage when possible.

| Parameter | Type                            | Default     | Description                                    |
| --------- | ------------------------------- | ----------- | ---------------------------------------------- |
| `start`   | `number`                        | —           | Zero-based index of the first block to clear.  |
| `end`     | `number`                        | `start + 1` | Exclusive end index (defaults to `start + 1`). |
| `options` | [`ClearOptions`](#clearoptions) | —           | —                                              |

* Returns: [`Promise<{blocks: number}\|null>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — `{ blocks }` with the count of cleared blocks when `opts.diff` is true, otherwise `null`.
* Throws:
  * `SESSION_CLOSED` if the core has been closed.
  * `ASSERTION` if the `start`/`end` range is invalid.

```js
await core.clear(4) // clear block 4 from your local cache
await core.clear(0, 10) // clear block 0-10 from your local cache
```

#### `await core.truncate(newLength, [options])` [#await-coretruncatenewlength-options]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1127)

Truncate the core to a smaller length.

| Parameter   | Type                                  | Default | Description                                                         |
| ----------- | ------------------------------------- | ------- | ------------------------------------------------------------------- |
| `newLength` | `number`                              | `0`     | The target length to truncate to (must be ≤ current `core.length`). |
| `options`   | [`TruncateOptions`](#truncateoptions) | `{}`    | —                                                                   |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the truncation has been signed and written to storage.
* Throws:
  * `SESSION_CLOSED` if the core has been closed.
  * `SESSION_NOT_WRITABLE` if the core is not writable.
  * `INVALID_OPERATION` if the truncation would break the manifest prologue.

### Reading, streams, and proofs [#reading-streams-and-proofs]

#### `await core.get(index, [options])` [#await-coregetindex-options]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L901)

Get a block of data. If the data is not available locally this method will prioritize and wait for the data to be downloaded.

| Parameter | Type                        | Description                                |
| --------- | --------------------------- | ------------------------------------------ |
| `index`   | `number`                    | Zero-based index of the block to retrieve. |
| `options` | [`GetOptions`](#getoptions) | —                                          |

* Returns: [`Promise<Buffer\|null>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — The block value (decoded per `valueEncoding`), or `null` if the block is not available and `wait` is `false`.
* Throws:
  * `SESSION_CLOSED` if the core has been closed.
  * `ASSERTION` if `index` is not a valid block index.

| Option           | Default     | Description                                                  |
| ---------------- | ----------- | ------------------------------------------------------------ |
| `wait`           | `true`      | wait for block to be downloaded                              |
| `onwait`         | —           | hook that is called if the get is waiting for download       |
| `timeout`        | `0`         | wait at max some milliseconds (0 means no timeout)           |
| `activeRequests` | `undefined` | Advanced option. Pass BlockRequest for replicating the block |
| `valueEncoding`  | —           | defaults to the core's valueEncoding                         |
| `decrypt`        | `true`      | automatically decrypts the block if encrypted                |
| `raw`            | `false`     | Return block without decoding                                |

```js
// get block #42
const block = await core.get(42)

// get block #43, but only wait 5s
const blockIfFast = await core.get(43, { timeout: 5000 })

// get block #44, but only if we have it locally
const blockLocal = await core.get(44, { wait: false })
```

#### `await core.has(start, [end])` [#await-corehasstart-end]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L851)

Check if the core has all blocks between `start` and `end`.

| Parameter | Type     | Default     | Description                                                                   |
| --------- | -------- | ----------- | ----------------------------------------------------------------------------- |
| `start`   | `number` | —           | Zero-based index of the first block to check.                                 |
| `end`     | `number` | `start + 1` | Exclusive end index (defaults to `start + 1`, that is checks a single block). |

* Returns: [`Promise<boolean>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — `true` if every block in `[start, end)` is available locally.
* Throws: `ASSERTION` if the `start`/`end` range is invalid.

```js
const hasBlock = await core.has(5)
const hasRange = await core.has(0, 10)
```

#### `await core.count(start, end)` [#await-corecountstart-end]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L883)

Count how many blocks between `start` and `end` the core has stored locally. Added in 11.38.0.

| Parameter | Type     | Default | Description                                                                                                                                |
| --------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `start`   | `number` | —       | Zero-based index of the first block to count.                                                                                              |
| `end`     | `number` | —       | Exclusive end index. It has no default: [`core.has()`](#await-corehasstart-end) defaults it to `start + 1`, but `count` throws without it. |

* Returns: [`Promise<number>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — how many blocks in `[start, end)` are available locally. Blocks past the core's length are not counted, and the result is `0` when `end` is not greater than `start`. [`core.has(start, end)`](#await-corehasstart-end) is `true` exactly when the result is `end - start`.
* Throws: `ASSERTION` if `start` or `end` is missing, negative, or not a number.

```js
// A replica that has downloaded blocks 1, 2 and 8 of a 10-block core
await core.count(0, 10) // 3
await core.count(1, 3) // 2
```

#### `await core.update([options])` [#await-coreupdateoptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L776)

Waits for initial proof of the new core length until all `findingPeers` calls have finished.

| Parameter | Type                              |
| --------- | --------------------------------- |
| `options` | [`UpdateOptions`](#updateoptions) |

* Returns: [`Promise<boolean>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — `true` if the core was updated to a new length, `false` otherwise.

| Option           | Default     | Description                                           |
| ---------------- | ----------- | ----------------------------------------------------- |
| `wait`           | `false`     | —                                                     |
| `activeRequests` | `undefined` | Advanced option. Pass requests for replicating blocks |
| `force`          | `false`     | Force an update even if core is writable.             |

```js
const updated = await core.update()

console.log('core was updated?', updated, 'length is', core.length)
```

#### `const [index, relativeOffset] = await core.seek(bytes, [options])` [#const-index-relativeoffset--await-coreseekbytes-options]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L809)

Seek to a byte offset.

| Parameter | Type                          | Description                                     |
| --------- | ----------------------------- | ----------------------------------------------- |
| `bytes`   | `number`                      | The byte offset to seek to (zero-based).        |
| `options` | [`SeekOptions`](#seekoptions) | Options controlling wait and timeout behaviour. |

* Returns: [`Promise<[number, number]>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — `[index, relativeOffset]`, where `index` is the data block the `bytes` is contained in and `relativeOffset` is the relative byte offset in the data block.
* Throws:
  * `SESSION_CLOSED` if the core has been closed.
  * `ASSERTION` if `bytes` is not a valid byte offset.

| Option           | Default     | Description                                           |
| ---------------- | ----------- | ----------------------------------------------------- |
| `wait`           | `true`      | wait for data to be downloaded                        |
| `timeout`        | `0`         | wait at max some milliseconds (0 means no timeout)    |
| `activeRequests` | `undefined` | Advanced option. Pass requests for replicating blocks |

```js
await core.append([Buffer.from('abc'), Buffer.from('d'), Buffer.from('efg')])

const first = await core.seek(1) // returns [0, 1]
const second = await core.seek(3) // returns [1, 0]
const third = await core.seek(5) // returns [2, 1]
```

#### `core.createReadStream([options])` [#corecreatereadstreamoptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1101)

Make a read stream to read a range of data out at once.

| Parameter | Type                                      |
| --------- | ----------------------------------------- |
| `options` | [`ReadStreamOptions`](#readstreamoptions) |

* Returns: `object` — A Readable stream that emits decoded blocks.

```js
// read the full core
const fullStream = core.createReadStream()

// read from block 10-14
const partialStream = core.createReadStream({ start: 10, end: 15 })

// pipe the stream somewhere using the .pipe method on Node.js or consume it as
// an async iterator

for await (const data of fullStream) {
  console.log('data:', data)
}
```

#### `core.createByteStream([options])` [#corecreatebytestreamoptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1109)

Make a byte stream to read a range of bytes.

| Parameter | Type                                      |
| --------- | ----------------------------------------- |
| `options` | [`ByteStreamOptions`](#bytestreamoptions) |

* Returns: `object` — A Readable stream that emits raw Buffer chunks spanning the requested byte range.

```js
// Read the full core
const fullStream = core.createByteStream()

// Read from byte 3, and from there read 50 bytes
const partialStream = core.createByteStream({ byteOffset: 3, byteLength: 50 })

// Consume it as an async iterator
for await (const data of fullStream) {
  console.log('data:', data)
}

// Or pipe it somewhere like any stream:
partialStream.pipe(process.stdout)
```

#### `await core.treeHash([length])` [#await-coretreehashlength]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1195)

Get the Merkle Tree hash of the core at a given length, defaulting to the current length of the core.

| Parameter | Type     | Default | Description                                         |
| --------- | -------- | ------- | --------------------------------------------------- |
| `length`  | `number` | `-1`    | Tree length to hash at (defaults to `core.length`). |

* Returns: [`Promise<Buffer>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — A 32-byte BLAKE2b hash of the Merkle tree roots at the given length.

```js
const hash = await core.treeHash()
console.log(hash.toString('hex'))
```

#### `await core.proof(opts)` [#await-coreproofopts]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1209)

Generate a proof (a `TreeProof` instance) for the request `opts`.

| Parameter | Type                            |
| --------- | ------------------------------- |
| `opts`    | [`ProofOptions`](#proofoptions) |

* Returns: [`Promise<object>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — A settled `TreeProof` object that can be serialised and sent to a remote peer.

#### `await core.verifyFullyRemote(proof)` [#await-coreverifyfullyremoteproof]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1226)

Note that you cannot seek & provide a block / hash request when upgrading.

| Parameter | Type     | Description                                                   |
| --------- | -------- | ------------------------------------------------------------- |
| `proof`   | `object` | A proof object as produced by a remote core's `core.proof()`. |

* Returns: [`Promise<object>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — the merkle tree batch from the proof.

```js
const batch = await core.verifyFullyRemote(remoteProof)
```

#### `await core.signable([length], [fork])` [#await-coresignablelength-fork]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1187)

Produce the signable payload for a given tree state. The payload encodes the
core's `key`, tree hash (`core.treeHash()`), `length`, and `fork`.

| Parameter | Type     | Default | Description                                         |
| --------- | -------- | ------- | --------------------------------------------------- |
| `length`  | `number` | `-1`    | The length to sign for (defaults to `core.length`). |
| `fork`    | `number` | `-1`    | The fork ID to include (defaults to `core.fork`).   |

* Returns: [`Promise<Buffer>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — a buffer which encodes the core's `key`, tree hash (`core.treeHash()`), `length`, & `fork`.

```js
const payload = await core.signable()
const sig = sodium.crypto_sign_detached(payload, secretKey)
```

#### `core.download([range])` [#coredownloadrange]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1113)

Download a range of data.

| Parameter | Type                              | Description                                                    |
| --------- | --------------------------------- | -------------------------------------------------------------- |
| `range`   | [`DownloadRange`](#downloadrange) | The block range to download. Omit to download the entire core. |

* Returns: `object` — A Download handle with a `.done()` promise and a `.destroy()` method to cancel.

| Option           | Default                | Description                                           |
| ---------------- | ---------------------- | ----------------------------------------------------- |
| `start`          | `startIndex`           | —                                                     |
| `end`            | `nonInclusiveEndIndex` | —                                                     |
| `blocks`         | —                      | —                                                     |
| `linear`         | `false`                | download range linearly and not randomly              |
| `activeRequests` | `undefined`            | Advanced option. Pass requests for replicating blocks |

```js
const download = core.download({ start: 0, end: 10 })
await download.done()
```

```js
// Note that this will never be considered downloaded as the range
// will keep waiting for new blocks to be appended.
core.download({ start: 0, end: -1 })
```

```js
core.download({ blocks: [4, 9, 7] })
```

```js
// will stop downloading now
range.destroy()
```

### Extensions and replication [#extensions-and-replication]

#### `core.registerExtension(name, handlers = {})` [#coreregisterextensionname-handlers--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1284)

Register a custom protocol extension. This is a legacy implementation and is no longer recommended. Creating a [`Protomux`](https://github.com/holepunchto/protomux) protocol is recommended instead.

| Parameter  | Type     | Default | Description                                                  |
| ---------- | -------- | ------- | ------------------------------------------------------------ |
| `name`     | `string` | —       | The unique name that identifies this extension across peers. |
| `handlers` | `object` | `{}`    | —                                                            |

* Returns: `object` — The extension object with `send(message, peer)`, `broadcast(message)`, and `destroy()` methods.

| Option      | Description                                               |
| ----------- | --------------------------------------------------------- |
| `encoding`  | Compact encoding to use for messages. Defaults to buffer  |
| `onmessage` | Callback for when a message for the extension is received |

This extension API is documented as legacy. For new protocol work, the upstream README recommends creating a [`Protomux`](/p2p/reference/helpers/protomux) protocol instead.

#### `ext.send(message, peer)` [#extsendmessage-peer]

Sends the `message` to a specific `peer`.

#### `ext.broadcast(message)` [#extbroadcastmessage]

Sends the `message` to all peers.

#### `ext.destroy()` [#extdestroy]

Unregister and remove extension from the hypercore.

#### `core.replicate(isInitiatorOrReplicationStream, opts = {})` [#corereplicateisinitiatororreplicationstream-opts--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L594)

Create a replication stream. You should pipe this to another Hypercore instance.

| Parameter                        | Type                                              | Default | Description                                                                                         |
| -------------------------------- | ------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `isInitiatorOrReplicationStream` | `boolean\|object`                                 | —       | `true`/`false` for the noise handshake role, or an existing stream / Protomux to attach to.         |
| `opts`                           | [`ProtocolStreamOptions`](#protocolstreamoptions) | `{}`    | are same as [`Hypercore.createProtocolStream()`](#hypercorecreateprotocolstreamisinitiator-opts--). |

* Returns: `object` — The replication stream (a raw duplex stream with a Protomux attached).

```js
// assuming we have two cores, localCore + remoteCore, sharing the same key
// on a server
const net = require('net')
const server = net.createServer(function (socket) {
  socket.pipe(remoteCore.replicate(false)).pipe(socket)
})

// on a client
const socket = net.connect(...)
socket.pipe(localCore.replicate(true)).pipe(socket)
```

#### `core.findingPeers()` [#corefindingpeers]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L754)

Create a hook that tells Hypercore you are finding peers for this core in the background. Call `done` when your current discovery iteration is done. If you're using [Hyperswarm](/p2p/reference/building-blocks/hyperswarm), you'd normally call this after a `swarm.flush()` finishes.

* Returns: `function` — A `done()` callback to call when peer discovery is complete.

```js
const done = core.findingPeers()
swarm.flush().then(done, done)
```

#### `await core.setAlwaysLatestBlock(enabled)` [#await-coresetalwayslatestblockenabled]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L311)

Set whether the replicator should always include a request for the latest block in an upgrade request (aka the peer has a length update). A runtime method for updating the `allowLatestBlock` option.

| Parameter | Type      | Description                                               |
| --------- | --------- | --------------------------------------------------------- |
| `enabled` | `boolean` | Whether to always request the latest block on an upgrade. |

### Storage inspection and mark-and-sweep [#storage-inspection-and-mark-and-sweep]

#### `await core.info([options])` [#await-coreinfooptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L770)

Get information about this core, such as its total size in bytes.

| Parameter | Type                          |
| --------- | ----------------------------- |
| `options` | [`InfoOptions`](#infooptions) |

* Returns: [`Promise<object>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — An `Info` object with `key`, `discoveryKey`, `length`, `contiguousLength`, `byteLength`, `fork`, `padding`, and optional `storage` fields.

```js
Info {
  key: Buffer(...),
  discoveryKey: Buffer(...),
  length: 18,
  contiguousLength: 16,
  byteLength: 742,
  fork: 0,
  padding: 8,
  storage: {
    oplog: 8192,
    tree: 4096,
    blocks: 4096,
    bitfield: 4096
  }
}
```

#### `await core.startMarking()` [#await-corestartmarking]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1055)

This enables marking mode for the "mark & sweep" approach to clear hypercore storage. When called the current markings are cleared.

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once marking mode is active and previous marks are cleared.
* Throws: `ASSERTION` if the core is already in gc mode, or is a named or atomic session.

```js
await core.startMarking()
await core.get(2)
await core.get(4)
await core.sweep() // All blocks but blocks 2 & 4 are cleared
```

#### `await core.markBlock(start, end = start + 1)` [#await-coremarkblockstart-end--start--1]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1032)

Manually mark a block or range of blocks to be retained when sweeping. Useful to mark blocks without loading them into memory. `end` is non-inclusive and defaults to `start + 1` so `core.markBlock(index)` only marks the block at `index`.

| Parameter | Type     | Default     | Description                                  |
| --------- | -------- | ----------- | -------------------------------------------- |
| `start`   | `number` | —           | Zero-based index of the first block to mark. |
| `end`     | `number` | `start + 1` | —                                            |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once all marks in the range have been written to storage.

```js
await core.markBlock(5)       // mark block 5
await core.markBlock(0, 10)   // mark blocks 0–9
```

#### `await core.clearMarkings()` [#await-coreclearmarkings]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1046)

Manually remove all markings. Automatically called when calling `core.startMarking()`.

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once all marks have been cleared from storage.

```js
await core.clearMarkings()
```

#### `await core.sweep(opts)` [#await-coresweepopts]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L1071)

Clear all unmarked blocks from storage.

| Parameter | Type                            | Default |
| --------- | ------------------------------- | ------- |
| `opts`    | [`SweepOptions`](#sweepoptions) | `{}`    |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once all unmarked blocks have been cleared.

The README describes the full mark-and-sweep flow as `startMarking()`, read or manually mark the blocks you want to keep, then `sweep()` to clear everything else.

### Lifecycle and local configuration [#lifecycle-and-local-configuration]

#### `await core.close([{ error }])` [#await-coreclose-error-]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L527)

Fully close this core. Passing an error via `{ error }` is optional and all pending replicator requests will be rejected with the error.

| Parameter | Type                            | Default | Description             |
| --------- | ------------------------------- | ------- | ----------------------- |
| `options` | [`CloseOptions`](#closeoptions) | `{}`    | Optional close options. |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the session (and underlying core if no other sessions remain) is fully closed.

```js
await core.close()
```

#### `await core.purge()` [#await-corepurge]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L957)

Close every session on this core and permanently delete its storage from disk. Unlike `core.clear()`, which drops selected blocks, `purge()` removes the entire core.

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the core's storage has been deleted.

#### `await core.ready()` [#await-coreready]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L708)

Wait for the core to fully open.

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the core is ready for reading and writing.

```js
const core = new Hypercore('./storage')
await core.ready()
console.log(core.key) // now available
```

#### `await core.setEncryption(encryption)` [#await-coresetencryptionencryption]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L279)

Set the encryption, which should satisfy the [HypercoreEncryption](https://github.com/holepunchto/hypercore-encryption) interface.

| Parameter    | Type           | Description                                                                                               |
| ------------ | -------------- | --------------------------------------------------------------------------------------------------------- |
| `encryption` | `object\|null` | An encryption provider with `padding`, `encrypt`, and `decrypt` methods, or `null` to disable encryption. |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the encryption provider has been installed.
* Throws: `ASSERTION` if the provider does not satisfy the `HypercoreEncryption` interface.

```js
await core.setEncryption(new DefaultEncryption(encryptionKey, core.key))
```

#### `await core.setEncryptionKey(key, [opts])` [#await-coresetencryptionkeykey-opts]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L273)

Set the encryption key.

| Parameter | Type                                                        | Description                                                        |
| --------- | ----------------------------------------------------------- | ------------------------------------------------------------------ |
| `key`     | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) | The 32-byte encryption key to use for block encryption/decryption. |
| `opts`    | [`SetEncryptionKeyOptions`](#setencryptionkeyoptions)       | —                                                                  |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the encryption provider has been installed.

#### `core.setKeyPair(keyPair)` [#coresetkeypairkeypair]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L299)

Update the core's `keyPair`. Advanced as the `keyPair` is used throughout Hypercore, for example verifying blocks, identifying the core, etc.

| Parameter | Type                                                                                        | Description                                  |
| --------- | ------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `keyPair` | [`{publicKey: Buffer, secretKey: Buffer}`](https://nodejs.org/api/buffer.html#class-buffer) | The new Ed25519 key pair to use for signing. |

* Returns: `void`

```js
core.setKeyPair({ publicKey: pubKey, secretKey: secKey })
```

#### `core.setActive(active)` [#coresetactiveactive]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L303)

Set the core to be active or not. A core is considered 'active' if it should linger to download blocks from peers.

| Parameter | Type      | Description                                                    |
| --------- | --------- | -------------------------------------------------------------- |
| `active`  | `boolean` | Pass `true` to mark the core as active, `false` to deactivate. |

* Returns: `void`

```js
core.setActive(false) // stop lingering for peer downloads
```

#### `await core.setGroup(topic)` [#await-coresetgrouptopic]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L294)

Set the group `topic` that the hypercore belongs to. Useful for grouping hypercores together that need to update a larger data structure (eg. `autobee`) that is comprised of them. See `corestore`'s `store.notifyGroup(topic)` for more details.

| Parameter | Type                                                        | Description          |
| --------- | ----------------------------------------------------------- | -------------------- |
| `topic`   | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) | is a 32 byte buffer. |

#### `await core.setUserData(key, value)` [#await-coresetuserdatakey-value]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L717)

Set a key in the User Data key-value store.

| Parameter | Type                                                                | Description                                  |
| --------- | ------------------------------------------------------------------- | -------------------------------------------- |
| `key`     | `string`                                                            | The user-data key (a string).                |
| `value`   | [`Buffer\|string`](https://nodejs.org/api/buffer.html#class-buffer) | The value to store (Buffer or UTF-8 string). |

* Returns: [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — Resolves once the value has been persisted to storage.

```js
await core.setUserData('version', Buffer.from('1.0'))
```

#### `await core.getUserData(key)` [#await-coregetuserdatakey]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L724)

Reads the local user-data value stored under `key`, resolving with its `Buffer`/string value or `null` if unset. User data is local-only and not replicated.

| Parameter | Type     | Description  |
| --------- | -------- | ------------ |
| `key`     | `string` | is a string. |

* Returns: [`Promise<Buffer\|null>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — the value for a key in the User Data key-value store.

```js
const value = await core.getUserData('version')
console.log(value && value.toString()) // '1.0'
```

#### `core.getManifest([options])` [#coregetmanifestoptions]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L646)

The core's manifest, optionally in its encoded wire form. Added in 11.35.0.

| Parameter     | Type      | Default | Description                                                      |
| ------------- | --------- | ------- | ---------------------------------------------------------------- |
| `options.raw` | `boolean` | `false` | Return the manifest encoded as a Buffer instead of as an object. |

* Returns: `object \| Buffer \| null` — the manifest, or `null` before the core is opened.

### Properties [#properties]

#### `core.writable` [#corewritable]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L78)

Can we append to or truncate this core?

* Returns: `boolean`

#### `core.readable` [#corereadable]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L77)

Can we read from this core? After closing the core this will be false.

* Returns: `boolean`

#### `core.id` [#coreid]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L630)

String containing the id (z-base-32 of the public key) identifying this core.

* Returns: `string\|null` — The z-base-32 encoded public key, or `null` before the core is opened.

#### `core.key` [#corekey]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L634)

Buffer containing the public key identifying this core.

* Returns: [`Buffer\|null`](https://nodejs.org/api/buffer.html#class-buffer) — The 32-byte public key, or `null` before the core is opened.

#### `core.keyPair` [#corekeypair]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L76)

Object containing buffers of the core's public and secret key

* Returns: [`{publicKey: Buffer, secretKey: Buffer\|null}\|null`](https://nodejs.org/api/buffer.html#class-buffer)

#### `core.discoveryKey` [#corediscoverykey]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L638)

Buffer containing a key derived from the core's public key. In contrast to `core.key` this key does not allow you to verify the data but can be used to announce or look for peers that are sharing the same core, without leaking the core key.

* Returns: [`Buffer\|null`](https://nodejs.org/api/buffer.html#class-buffer) — The 32-byte discovery key, or `null` before the core is opened.

#### `core.length` [#corelength]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L651)

How many blocks of data are available on this core.

* Returns: `number` — The total number of blocks in the core (0 before the core is opened).

#### `core.byteLength` [#corebytelength]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L663)

The cumulative size, in bytes, of all blocks in the core.

* Returns: `number` — Total byte length of the core (0 before the core is opened).

#### `core.manifest` [#coremanifest]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L642)

The core's manifest—the signed description of its cryptographic configuration (version, signers, prologue, and so on).

* Returns: `object \| null` — The manifest object, or `null` before the core is opened.

See [`core.getManifest()`](#coregetmanifestoptions) for the encoded form.

#### `core.signedLength` [#coresignedlength]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L656)

How many blocks of data are available on this core that have been signed by a quorum. This is equal to `core.length` for Hypercores with a single signer.

* Returns: `number` — The number of quorum-signed blocks (0 before the core is opened).

#### `core.contiguousLength` [#corecontiguouslength]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L674)

How many blocks are contiguously available starting from the first block of this core.

* Returns: `number` — The local contiguous length (0 before the core is opened).

#### `core.remoteContiguousLength` [#coreremotecontiguouslength]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L669)

How many blocks are contiguously available starting from the first block of this core on any known remote. This is only updated when a remote thinks it is fully contiguous such that they have all known blocks.

* Returns: `number` — The remote contiguous length (0 before the core is opened).

#### `core.fork` [#corefork]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L683)

What is the current fork id of this core?

* Returns: `number` — The current fork counter (incremented on each truncation; 0 before the core is opened).

#### `core.padding` [#corepadding]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L688)

How much padding is applied to each block of this core? Will be `0` unless block encryption is enabled.

* Returns: `number` — Number of padding bytes prepended to each block (0 when encryption is disabled).

#### `core.peers` [#corepeers]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L696)

Array of current peers the core is replicating with.

* Returns: [`Array<object>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) — Live array of Replicator peer objects (empty before the core is opened).

### Events [#events]

#### `core.on('close')` [#coreonclose]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L362)

Emitted when the core has been fully closed.

#### `core.on('ready')` [#coreonready]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L375)

Emitted after the core has initially opened all its internal state.

#### `core.on('append')` [#coreonappend]

Emitted when the core has been appended to (that is has a new length / byteLength), either locally or remotely.

#### `core.on('truncate', ancestors, forkId)` [#coreontruncate-ancestors-forkid]

Emitted when the core has been truncated, either locally or remotely.

#### `core.on('peer-add')` [#coreonpeer-add]

Emitted when a new connection has been established with a peer.

#### `core.on('peer-remove')` [#coreonpeer-remove]

Emitted when a peer's connection has been closed.

#### `core.on('upload', index, byteLength, peer)` [#coreonupload-index-bytelength-peer]

Emitted when a block is uploaded to a peer.

#### `core.on('download', index, byteLength, peer)` [#coreondownload-index-bytelength-peer]

Emitted when a block is downloaded from a peer.

#### `core.on('remote-contiguous-length', length)` [#coreonremote-contiguous-length-length]

Emitted when the max known contiguous `length` from a remote, that is `core.remoteContiguousLength`, is updated. Note this is not emitted when core is truncated.

#### `core.on('migrate', key)` [#coreonmigrate-key]

Emitted when the core migrates to a new key—for example after a manifest change. The listener receives the new `core.key`.

### Static helpers [#static-helpers]

#### `Hypercore.MAX_SUGGESTED_BLOCK_SIZE` [#hypercoremax_suggested_block_size]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L118)

The constant for max size (15MB) for blocks appended to Hypercore. This max ensures blocks are replicated smoothly.

* Returns: `number`

#### `Hypercore.key(manifest, options = {})` [#hypercorekeymanifest-options--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L133)

`options` include:

| Parameter  | Type                                                                | Default | Description                                                                                                |
| ---------- | ------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `manifest` | [`Buffer\|object`](https://nodejs.org/api/buffer.html#class-buffer) | —       | A 32-byte public key Buffer, an encoded manifest Buffer, or a full manifest object with a `signers` array. |
| `options`  | [`KeyOptions`](#keyoptions)                                         | `{}`    | —                                                                                                          |

* Returns: [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) — the key for a given manifest.

A Buffer is read as a public key only when it is exactly 32 bytes; any other length is parsed as an encoded manifest. Added in 11.35.0—on earlier releases every Buffer is treated as a public key.

#### `Hypercore.parseManifest(manifest, [key])` [#hypercoreparsemanifestmanifest-key]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L143)

Decode and validate a manifest. Added in 11.35.0.

| Parameter  | Type                                                                | Description                                                      |
| ---------- | ------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `manifest` | [`Buffer\|object`](https://nodejs.org/api/buffer.html#class-buffer) | An encoded manifest Buffer, or a manifest object.                |
| `key`      | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer)         | Optional. When given, the parsed manifest must hash to this key. |

* Returns: `object \| null` — the parsed manifest, or `null` when it cannot be created.
* Throws `BAD_ARGUMENT` if `quorum` exceeds the number of `signers`, and `INVALID_CHECKSUM` if `key` is supplied and the manifest does not hash to it.

#### `Hypercore.discoveryKey(key)` [#hypercorediscoverykeykey]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L158)

Derive the discovery key from a Hypercore public key. The discovery key
can safely be shared to announce the core without exposing the read key.

| Parameter | Type                                                        | Description                       |
| --------- | ----------------------------------------------------------- | --------------------------------- |
| `key`     | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) | The 32-byte Hypercore public key. |

* Returns: [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) — the discovery key for the provided `key`.

```js
const dKey = Hypercore.discoveryKey(core.key)
```

#### `Hypercore.blockEncryptionKey(key, encryptionKey)` [#hypercoreblockencryptionkeykey-encryptionkey]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L162)

Derive a block-level encryption key from the Hypercore public key and a
master encryption key using BLAKE2b.

| Parameter       | Type                                                        | Description                        |
| --------------- | ----------------------------------------------------------- | ---------------------------------- |
| `key`           | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) | The 32-byte Hypercore public key.  |
| `encryptionKey` | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) | The 32-byte master encryption key. |

* Returns: [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) — a block encryption key derived from the `key` and `encryptionKey`.

```js
const blockKey = Hypercore.blockEncryptionKey(core.key, encryptionKey)
```

#### `Hypercore.getProtocolMuxer(stream)` [#hypercoregetprotocolmuxerstream]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L166)

Extract the Protomux instance attached to a Hypercore protocol stream.

| Parameter | Type     | Description                                                                                            |
| --------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `stream`  | `object` | A Hypercore protocol stream (as returned by `core.replicate()` or `Hypercore.createProtocolStream()`). |

* Returns: `object` — a protomux instance from the provided `stream` Hypercore protocol stream.

```js
const stream = core.replicate(true)
const mux = Hypercore.getProtocolMuxer(stream)
```

#### `Hypercore.createCore(storage, opts)` [#hypercorecreatecorestorage-opts]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L170)

Create the raw internal Core object directly, bypassing the Hypercore
session layer. Useful for low-level tooling that needs direct storage access.

| Parameter | Type                                    | Description                                             |
| --------- | --------------------------------------- | ------------------------------------------------------- |
| `storage` | `string\|object`                        | Path to a storage directory, or a CoreStorage instance. |
| `opts`    | [`HypercoreOptions`](#hypercoreoptions) | Options forwarded to the Core constructor.              |

* Returns: `object` — the internal core using the `storage` and `opts` without creating a full Hypercore instance.

```js
const core = Hypercore.createCore('./storage', { key: myKey })
```

#### `Hypercore.createProtocolStream(isInitiator, opts = {})` [#hypercorecreateprotocolstreamisinitiator-opts--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L174)

Create an encrypted noise stream with a protomux instance attached used for Hypercore's replication protocol.

| Parameter     | Type                                              | Default | Description                                                                                                            |
| ------------- | ------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
| `isInitiator` | `boolean\|object`                                 | —       | can be a framed stream, a protomux or a boolean for whether the stream should be the initiator in the noise handshake. |
| `opts`        | [`ProtocolStreamOptions`](#protocolstreamoptions) | `{}`    | —                                                                                                                      |

* Returns: `object` — The outer raw stream with a `.noiseStream.userData` Protomux attached.

#### `Hypercore.defaultStorage(storage, opts = {})` [#hypercoredefaultstoragestorage-opts--]

[src](https://github.com/holepunchto/hypercore/blob/v11.38.0/index.js#L208)

Wrap a path or existing CoreStorage object into a CoreStorage instance.
Called internally by the constructor; exposed for advanced use.

| Parameter | Type                                              | Default | Description                                                                 |
| --------- | ------------------------------------------------- | ------- | --------------------------------------------------------------------------- |
| `storage` | `string\|object`                                  | —       | Directory path string or an existing CoreStorage instance (returned as-is). |
| `opts`    | [`DefaultStorageOptions`](#defaultstorageoptions) | `{}`    | Extra options forwarded to the CoreStorage constructor.                     |

* Returns: `object` — a default hypercore storage.

```js
const storage = Hypercore.defaultStorage('./my-core')
```

## Types [#types]

### HypercoreOptions [#hypercoreoptions]

Options for creating or opening a Hypercore instance.

| Property        | Type                                                                                        | Default | Description                                                                           |
| --------------- | ------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------- |
| `key`           | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer)                                 | —       | The public key of the core (32 bytes). Omit to create a new writable core.            |
| `keyPair`       | [`{publicKey: Buffer, secretKey: Buffer}`](https://nodejs.org/api/buffer.html#class-buffer) | —       | Ed25519 key pair for signing appended blocks.                                         |
| `encryptionKey` | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer)                                 | —       | A 32-byte key to enable block encryption.                                             |
| `encryption`    | `object`                                                                                    | —       | Custom encryption provider satisfying the HypercoreEncryption interface.              |
| `valueEncoding` | `string\|object`                                                                            | —       | Encoding for block values (for example `'utf8'`, `'json'`, a compact-encoding codec). |
| `writable`      | `boolean`                                                                                   | `true`  | Set `false` to open the session read-only.                                            |
| `weak`          | `boolean`                                                                                   | `false` | Do not keep the underlying core alive when this session is the last one.              |
| `snapshot`      | `boolean`                                                                                   | `false` | Snapshot the core length at open time; blocks beyond that length are invisible.       |
| `timeout`       | `number`                                                                                    | `0`     | Default timeout in ms for `get()` / `seek()` (0 = no timeout).                        |
| `wait`          | `boolean`                                                                                   | `true`  | Wait for blocks to download when `get()` / `seek()` are called.                       |
| `onwait`        | `function`                                                                                  | —       | Called whenever `get()` triggers a network wait: `onwait(index, core)`.               |
| `onseq`         | `function`                                                                                  | —       | Called on each `get()` call with the block index: `onseq(index, core)`.               |
| `compat`        | `boolean`                                                                                   | `false` | Enable legacy (v9) manifest compatibility mode.                                       |
| `exclusive`     | `boolean`                                                                                   | `false` | Acquire an exclusive write lock on the core.                                          |

### KeyOptions [#keyoptions]

Options for Hypercore.key() static method.

| Property    | Type                                                        | Default | Description                                                                        |
| ----------- | ----------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------- |
| `compat`    | `boolean`                                                   | `false` | If `true`, returns the first signer's raw public key instead of the manifest hash. |
| `version`   | `number`                                                    | —       | Manifest version number (used when building the manifest from a raw key).          |
| `namespace` | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer) | —       | Namespace buffer to include in the manifest when building from a raw key.          |

### ProtocolStreamOptions [#protocolstreamoptions]

Options for Hypercore.createProtocolStream().

| Property         | Type       | Default | Description                                                              |
| ---------------- | ---------- | ------- | ------------------------------------------------------------------------ |
| `stream`         | `object`   | —       | An existing raw stream to wrap; avoids creating a new NoiseSecretStream. |
| `ondiscoverykey` | `function` | —       | Called with a discovery key Buffer when a remote announces a new core.   |
| `keepAlive`      | `boolean`  | `true`  | Send keep-alive pings every 5 s to prevent idle disconnection.           |

### DefaultStorageOptions [#defaultstorageoptions]

Options for Hypercore.defaultStorage(). If the first argument is already a storage instance it is returned as-is; otherwise it is treated as a directory and the options are forwarded verbatim to the [`hypercore-storage`](https://github.com/holepunchto/hypercore-storage) constructor. Hypercore itself reads none of them.

### SessionOptions [#sessionoptions]

Options for core.session() / core.snapshot().

| Property        | Type             | Default | Description                                                   |
| --------------- | ---------------- | ------- | ------------------------------------------------------------- |
| `valueEncoding` | `string\|object` | —       | Override the value encoding for this session only.            |
| `writable`      | `boolean`        | —       | Override the writable flag for this session.                  |
| `snapshot`      | `boolean`        | `false` | Lock the visible length to the current core length.           |
| `timeout`       | `number`         | —       | Per-session get/seek timeout in ms.                           |
| `wait`          | `boolean`        | —       | Whether to wait for remote blocks by default.                 |
| `weak`          | `boolean`        | —       | Do not keep the core alive when this session is the last one. |
| `exclusive`     | `boolean`        | `false` | Acquire an exclusive write lock on the core.                  |
| `atom`          | `object`         | —       | A storage atom to stage writes against.                       |
| `name`          | `string`         | —       | Named session; writes are staged under this name.             |
| `checkout`      | `number`         | —       | Roll back a named/atom session to this length after opening.  |

### SetEncryptionKeyOptions [#setencryptionkeyoptions]

Options for core.setEncryptionKey().

| Property | Type      | Default | Description                                                               |
| -------- | --------- | ------- | ------------------------------------------------------------------------- |
| `block`  | `boolean` | `false` | Treat the supplied key as a raw block-level key rather than deriving one. |

### GetOptions [#getoptions]

Options for core.get().

| Property        | Type             | Default | Description                                                                 |
| --------------- | ---------------- | ------- | --------------------------------------------------------------------------- |
| `wait`          | `boolean`        | `true`  | Wait for the block to be downloaded from a peer if not available locally.   |
| `timeout`       | `number`         | `0`     | Max ms to wait for replication (0 = use core default).                      |
| `valueEncoding` | `string\|object` | —       | Decode the block with this encoding instead of the core's default.          |
| `decrypt`       | `boolean`        | `true`  | Decrypt the block when encryption is enabled.                               |
| `raw`           | `boolean`        | `false` | Return the raw Buffer without decoding or decrypting.                       |
| `onwait`        | `function`       | —       | Called if this specific get triggers a network wait: `onwait(index, core)`. |

### SeekOptions [#seekoptions]

Options for core.seek().

| Property  | Type      | Default | Description                                             |
| --------- | --------- | ------- | ------------------------------------------------------- |
| `wait`    | `boolean` | `true`  | Wait for the necessary blocks to download if not local. |
| `timeout` | `number`  | `0`     | Max ms to wait (0 = use core default).                  |

### ClearOptions [#clearoptions]

Options for core.clear().

| Property | Type      | Default | Description                                                                     |
| -------- | --------- | ------- | ------------------------------------------------------------------------------- |
| `diff`   | `boolean` | `false` | Return a `{ blocks: number }` object counting cleared blocks instead of `null`. |

### UpdateOptions [#updateoptions]

Options for core.update().

| Property | Type      | Default | Description                                              |
| -------- | --------- | ------- | -------------------------------------------------------- |
| `wait`   | `boolean` | `true`  | Wait for remote peers to send a new signed length proof. |
| `force`  | `boolean` | `false` | Force an update even when the core is writable.          |

### TruncateOptions [#truncateoptions]

Options for core.truncate().

| Property    | Type                                                                                        | Default | Description                                                            |
| ----------- | ------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------- |
| `fork`      | `number`                                                                                    | —       | The fork ID to assign after truncation (defaults to `state.fork + 1`). |
| `keyPair`   | [`{publicKey: Buffer, secretKey: Buffer}`](https://nodejs.org/api/buffer.html#class-buffer) | —       | Key pair to sign the truncation (defaults to `core.keyPair`).          |
| `signature` | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer)                                 | —       | Pre-computed signature for the truncation.                             |

### AppendOptions [#appendoptions]

Options for core.append().

| Property    | Type                                                                                        | Default | Description                                                       |
| ----------- | ------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------- |
| `keyPair`   | [`{publicKey: Buffer, secretKey: Buffer}`](https://nodejs.org/api/buffer.html#class-buffer) | —       | Key pair to sign the batch (defaults to `core.keyPair`).          |
| `signature` | [`Buffer`](https://nodejs.org/api/buffer.html#class-buffer)                                 | —       | Pre-computed signature.                                           |
| `maxLength` | `number`                                                                                    | —       | Refuse to append if the resulting length would exceed this value. |

### InfoOptions [#infooptions]

Options for core.info().

| Property  | Type      | Default | Description                                         |
| --------- | --------- | ------- | --------------------------------------------------- |
| `storage` | `boolean` | `false` | Include per-file storage byte counts in the result. |

### ReadStreamOptions [#readstreamoptions]

Options for core.createReadStream().

| Property   | Type      | Default | Description                                                                    |
| ---------- | --------- | ------- | ------------------------------------------------------------------------------ |
| `start`    | `number`  | `0`     | Index of the first block to read.                                              |
| `end`      | `number`  | —       | Index of the block to stop at (exclusive).                                     |
| `live`     | `boolean` | `false` | Keep streaming new blocks as they are appended.                                |
| `snapshot` | `boolean` | `true`  | Snap the end to the current length at open time (ignored when `live` is true). |
| `wait`     | `boolean` | `true`  | Wait for blocks to download.                                                   |
| `timeout`  | `number`  | `0`     | Per-block timeout in ms (0 = use core default).                                |

### ByteStreamOptions [#bytestreamoptions]

Options for core.createByteStream().

| Property     | Type     | Default | Description                                       |
| ------------ | -------- | ------- | ------------------------------------------------- |
| `byteOffset` | `number` | `0`     | Start reading from this byte position.            |
| `byteLength` | `number` | —       | Number of bytes to read (-1 = until end of core). |
| `prefetch`   | `number` | `32`    | Number of blocks to prefetch ahead.               |

### DownloadRange [#downloadrange]

Download range descriptor for core.download().

| Property | Type      | Default | Description                                                          |
| -------- | --------- | ------- | -------------------------------------------------------------------- |
| `start`  | `number`  | `0`     | First block index to download.                                       |
| `end`    | `number`  | —       | Last block index to download (exclusive; defaults to `core.length`). |
| `linear` | `boolean` | `false` | Download blocks in sequential order.                                 |

### ProofOptions [#proofoptions]

Options for core.proof().

| Property   | Type     | Default | Description                                                    |
| ---------- | -------- | ------- | -------------------------------------------------------------- |
| `block`    | `object` | —       | Request a block proof: `{ index: number }`.                    |
| `hash`     | `object` | —       | Request a hash proof: `{ index: number }`.                     |
| `seek`     | `object` | —       | Request a seek proof: `{ bytes: number }`.                     |
| `upgrade`  | `object` | —       | Request an upgrade proof: `{ start: number, length: number }`. |
| `manifest` | `object` | —       | Include a manifest proof.                                      |

### CommitOptions [#commitoptions]

Options for core.commit().

| Property  | Type                                                                                        | Default | Description                                 |
| --------- | ------------------------------------------------------------------------------------------- | ------- | ------------------------------------------- |
| `keyPair` | [`{publicKey: Buffer, secretKey: Buffer}`](https://nodejs.org/api/buffer.html#class-buffer) | —       | Key pair used to sign the committed blocks. |

### SweepOptions [#sweepoptions]

Options for core.sweep().

| Property    | Type     | Default | Description                                                        |
| ----------- | -------- | ------- | ------------------------------------------------------------------ |
| `batchSize` | `number` | `1000`  | Number of clear operations to run in parallel per sweep iteration. |

### CloseOptions [#closeoptions]

Options for core.close().

| Property | Type    | Default | Description                                        |
| -------- | ------- | ------- | -------------------------------------------------- |
| `error`  | `Error` | —       | Error to reject pending replication requests with. |

## Errors [#errors]

Coded errors this module can throw — catch them via `err.code`.

| Error                  | Thrown when                                                                                                                                                                                                                                                        |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ASSERTION`            | if `index` is not a valid block index.; if `bytes` is not a valid byte offset.; if the `start`/`end` range is invalid.; if the provider does not satisfy the `HypercoreEncryption` interface.; if the core is already in gc mode, or is a named or atomic session. |
| `BAD_ARGUMENT`         | if an appended block exceeds the maximum suggested block size.                                                                                                                                                                                                     |
| `INVALID_OPERATION`    | if the append is inconsistent with the manifest prologue.; if the truncation would break the manifest prologue.; if no database batch was passed, or the tree changed during the batch.                                                                            |
| `SESSION_CLOSED`       | if called on a core that is already closing.; if the core has been closed.                                                                                                                                                                                         |
| `SESSION_NOT_WRITABLE` | if the core is not writable.                                                                                                                                                                                                                                       |

## See also [#see-also]

* [Replicate and persist with Hypercore](/p2p/how-to/store-and-replicate/replicate-and-persist-with-hypercore)—pair a single core with peer discovery and replication.
* [Work with many Hypercores using Corestore](/p2p/how-to/store-and-replicate/work-with-many-hypercores-using-corestore)—recommended pattern when one process manages multiple cores.
* [Corestore](/p2p/reference/helpers/corestore)—helper reference for creating, naming, and co-replicating groups of Hypercores.
* [Hyperbee](/p2p/reference/building-blocks/hyperbee)—sorted key/value B-tree built directly on top of a Hypercore.
* [Hyperdrive](/p2p/reference/building-blocks/hyperdrive)—filesystem abstraction whose metadata and blob stores are Hypercore-backed.
* [Compact encoding](/p2p/reference/helpers/compact-encoding)—binary encoding toolkit used to structure Hypercore block payloads.
