# Hyperswarm



<Status level="stable" />

Hyperswarm is the high-level networking layer for discovering peers by a shared 32-byte topic and opening encrypted connections between them. Prefer one swarm instance per app and join multiple topics on that same instance when possible.

## Install [#install]

```sh
npm i hyperswarm
```

## Quickstart [#quickstart]

```js
import Hyperswarm from 'hyperswarm'

const server = new Hyperswarm()
const client = new Hyperswarm()

server.on('connection', socket => {
  socket.end('hello from the server')
})

client.on('connection', socket => {
  socket.once('data', async buf => {
    console.log(buf.toString())
    await Promise.all([client.destroy(), server.destroy()])
  })
})

const topic = Buffer.alloc(32).fill('pear-docs-topic')
const discovery = server.join(topic, { server: true, client: false })
await discovery.flushed()

client.join(topic, { server: false, client: true })
await client.flush()
```

## API Reference [#api-reference]

### Constructor and state [#constructor-and-state]

#### `new Hyperswarm(opts = {})` [#new-hyperswarmopts--]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L23)

* Signature: `const swarm = new Hyperswarm(opts)`
* Parameters:
  * `opts.keyPair`: Noise key pair to use for DHT listen and connect operations. Defaults to a key pair derived from `opts.seed`, or a random one.
  * `opts.seed`: 32-byte seed used to derive a deterministic key pair.
  * `opts.maxPeers`: Maximum number of peer connections to keep open. Defaults to `64`.
  * `opts.maxClientConnections`: Maximum number of outbound (client) connections. Defaults to `Infinity`.
  * `opts.maxServerConnections`: Maximum number of inbound (server) connections. Defaults to `Infinity`.
  * `opts.maxParallel`: Maximum number of connection attempts running in parallel. Defaults to `3`.
  * `opts.firewall`: Synchronous function `(remotePublicKey, payload) => boolean` that rejects a peer when it returns `true`. Defaults to allowing all peers.
  * `opts.relayThrough`: Public key of a node to relay connections through, or a function `(force, swarm) => publicKey | null` that picks one. A plain key is used only when `force` is set or the swarm's DHT node is randomized. `force` becomes `true` for a peer after a client connection fails with `HOLEPUNCH_ABORTED`, `HOLEPUNCH_DOUBLE_RANDOMIZED_NATS`, `REMOTE_NOT_HOLEPUNCHABLE`, or—from v4.17.1—`CANNOT_HOLEPUNCH`, and its retry backoff resets so the relayed attempt runs promptly.
  * `opts.dht`: Existing `hyperdht` instance to reuse instead of creating one internally.
* Returns: A new `Hyperswarm` instance.
* Example:

```js
const swarm = new Hyperswarm({ maxPeers: 32 })
await swarm.listen()
```

#### `swarm.connecting` [#swarmconnecting]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L64)

* Signature: `swarm.connecting`
* Returns: `number` count of outbound connections still opening.
* Example:

```js
if (swarm.connecting > 0) console.log('connecting...')
```

#### `swarm.connections` [#swarmconnections]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L65)

* Signature: `swarm.connections`
* Returns: `Set` of active encrypted duplex connections.
* Example:

```js
for (const socket of swarm.connections) socket.write('ping')
```

#### `swarm.peers` [#swarmpeers]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L66)

* Signature: `swarm.peers`
* Returns: `Map<string, PeerInfo>` keyed by the remote Noise public key as a hex string.
* Example:

```js
for (const [key, peer] of swarm.peers) {
  console.log(key, peer.prioritized)
}
```

#### `swarm.dht` [#swarmdht]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L38)

* Signature: `swarm.dht`
* Returns: The underlying `hyperdht` instance used by the swarm.
* Example:

```js
console.log('bootstrap ready:', !!swarm.dht)
```

### Topic membership [#topic-membership]

#### `swarm.join(topic, opts = {})` [#swarmjointopic-opts--]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L505)

* Signature: `const discovery = swarm.join(topic, opts)`
* Parameters:
  * `topic`: 32-byte `Buffer` that identifies the swarm topic.
  * `opts.server`: Announce on the DHT and accept inbound connections for this topic. Defaults to `true`.
  * `opts.client`: Query the DHT and connect to discovered servers for this topic. Defaults to `true`.
  * `opts.limit`: Maximum peers to connect to for this topic. Defaults to `Infinity`.
* Returns: A `PeerDiscovery` object for the topic.
* Example:

```js
const discovery = swarm.join(topic, { server: true, client: false })
await discovery.flushed()
```

Client mode discovers and dials servers for a topic. Server mode announces that topic and accepts inbound connections. Connections opened in client mode update `peerInfo.topics`; inbound server connections are not tied to a single topic.

#### `await swarm.leave(topic)` [#await-swarmleavetopic]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L529)

* Signature: `await swarm.leave(topic)`
* Parameters:
  * `topic`: 32-byte `Buffer` previously joined with `swarm.join(...)`.
* Returns: A promise that resolves after discovery and announcement for that topic stop.
* Example:

```js
await swarm.leave(topic)
```

Leaving a topic stops new discovery work but does not close already-open connections.

#### `swarm.status(topic)` [#swarmstatustopic]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L491)

* Signature: `const discovery = swarm.status(topic)`
* Parameters:
  * `topic`: 32-byte `Buffer` for a joined topic.
* Returns: The current `PeerDiscovery` for that topic, or `null` if the topic is not active.
* Example:

```js
const discovery = swarm.status(topic)
if (discovery) await discovery.refresh()
```

`status(topic)` returns the underlying `PeerDiscovery`, whose `refresh()` takes no arguments and reannounces or re-looks up with the topic's existing client/server configuration. The object returned by `swarm.join(...)` is a session over that discovery and accepts `{ client, server }` on `refresh(...)`.

#### `await swarm.flush()` [#await-swarmflush]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L571)

* Signature: `await swarm.flush()`
* Returns: A promise that resolves after pending DHT announces complete and queued peer connections have been processed.
* Example:

```js
swarm.join(topic, { client: true, server: false })
await swarm.flush()
```

`flush()` is global to the swarm rather than scoped to one topic, so it can be comparatively expensive.

### Direct peers and events [#direct-peers-and-events]

#### `swarm.joinPeer(noisePublicKey)` [#swarmjoinpeernoisepublickey]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L547)

* Signature: `swarm.joinPeer(noisePublicKey)`
* Parameters:
  * `noisePublicKey`: 32-byte `Buffer` containing the remote peer's Noise public key.
* Returns: Nothing. Hyperswarm starts and maintains a direct connection attempt to that peer.
* Example:

```js
swarm.joinPeer(remotePublicKey)
```

#### `swarm.leavePeer(noisePublicKey)` [#swarmleavepeernoisepublickey]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L560)

* Signature: `swarm.leavePeer(noisePublicKey)`
* Parameters:
  * `noisePublicKey`: 32-byte `Buffer` for a peer previously targeted with `joinPeer(...)`.
* Returns: Nothing. Future reconnect attempts stop.
* Example:

```js
swarm.leavePeer(remotePublicKey)
```

If the peer is already connected, `leavePeer(...)` does not close that existing socket.

#### `swarm.on('connection', (socket, peerInfo) => {})` [#swarmonconnection-socket-peerinfo--]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L245)

* Signature: `swarm.on('connection', (socket, peerInfo) => {})`
* Parameters:
  * `socket`: End-to-end encrypted duplex stream for the peer connection.
  * `peerInfo`: `PeerInfo` object describing the connected peer.
* Returns: The swarm emits this event whenever a new peer connection opens.
* Example:

```js
swarm.on('connection', (socket, peerInfo) => {
  console.log(peerInfo.publicKey)
  socket.write('hello')
})
```

#### `swarm.on('update', () => {})` [#swarmonupdate---]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L105)

* Signature: `swarm.on('update', () => {})`
* Returns: The swarm emits this event whenever internal counters or connection state change.
* Example:

```js
swarm.on('update', () => {
  console.log(swarm.connecting, swarm.connections.size)
})
```

#### `swarm.on('ban', (peerInfo, err) => {})` [#swarmonban-peerinfo-err--]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L488)

* Signature: `swarm.on('ban', (peerInfo, err) => {})`
* Parameters:
  * `peerInfo`: Banned peer metadata.
  * `err`: Error describing why the peer was banned, such as a firewall rejection.
* Returns: The swarm emits this event after a peer becomes banned.
* Example:

```js
swarm.on('ban', (peerInfo, err) => {
  console.log('banned', peerInfo.publicKey, err?.message)
})
```

### Listening and lifecycle [#listening-and-lifecycle]

#### `await swarm.listen()` [#await-swarmlisten]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L495)

* Signature: `await swarm.listen()`
* Returns: A promise that resolves once the swarm is listening for inbound connections.
* Example:

```js
await swarm.listen()
```

`listen()` is usually called for you after the first `join(...)`, but it is available when you want listening to start earlier.

#### `await swarm.suspend({ log } = {})` [#await-swarmsuspend-log---]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L610)

* Signature: `await swarm.suspend({ log })`
* Parameters:
  * `log`: Optional logging function used while the swarm suspends networking. Defaults to a no-op.
* Returns: A promise that resolves after peer connections, server listening, and discovery are suspended.
* Example:

```js
await swarm.suspend({ log: console.log })
```

#### `await swarm.resume({ log } = {})` [#await-swarmresume-log---]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L646)

* Signature: `await swarm.resume({ log })`
* Parameters:
  * `log`: Optional logging function used while the swarm resumes networking. Defaults to a no-op.
* Returns: A promise that resolves after the DHT, listening server, and discovery resume.
* Example:

```js
await swarm.resume({ log: console.log })
```

#### `await swarm.destroy({ force } = {})` [#await-swarmdestroy-force---]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/index.js#L592)

* Signature: `await swarm.destroy({ force })`
* Parameters:
  * `force`: Optional boolean that skips graceful topic cleanup when `true`.
* Returns: A promise that resolves after the swarm closes its server, discovery work, and underlying DHT instance.
* Example:

```js
await swarm.destroy()
```

### `PeerDiscovery` [#peerdiscovery]

#### `await discovery.flushed()` [#await-discoveryflushed]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-discovery.js#L191)

* Signature: `await discovery.flushed()`
* Returns: A promise that resolves once a server-mode topic has been fully announced on the DHT.
* Example:

```js
const discovery = swarm.join(topic, { server: true, client: false })
await discovery.flushed()
```

#### `await discovery.refresh({ client, server })` [#await-discoveryrefresh-client-server-]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-discovery.js#L310)

* Signature: `await discovery.refresh({ client, server, limit })`
* Parameters:
  * `client`: Optional boolean to enable or disable client lookups. Defaults to the session's current value.
  * `server`: Optional boolean to enable or disable server announcements. Defaults to the session's current value.
  * `limit`: Optional maximum number of peers to connect to for this topic. Defaults to `Infinity`.
* Returns: A promise that resolves after the topic configuration is refreshed. Throws if both `client` and `server` are `false`.
* Example:

```js
await discovery.refresh({ client: true, server: true })
```

Refreshing a server-mode discovery also triggers a new DHT announcement for that topic.

#### `await discovery.destroy()` [#await-discoverydestroy]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-discovery.js#L333)

* Signature: `await discovery.destroy()`
* Returns: A promise that resolves after discovery and announcements for that topic stop.
* Example:

```js
await discovery.destroy()
```

### `PeerInfo` [#peerinfo]

#### `peerInfo.publicKey` [#peerinfopublickey]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-info.js#L17)

* Signature: `peerInfo.publicKey`
* Returns: The peer's Noise public key as a `Buffer`.
* Example:

```js
console.log(peerInfo.publicKey)
```

#### `peerInfo.topics` [#peerinfotopics]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-info.js#L33)

* Signature: `peerInfo.topics`
* Returns: Array of joined topics associated with the peer when the local swarm connected in client mode.
* Example:

```js
for (const topic of peerInfo.topics) console.log(topic)
```

#### `peerInfo.prioritized` [#peerinfoprioritized]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-info.js#L52)

* Signature: `peerInfo.prioritized`
* Returns: `true` when the peer's connection priority is at or above normal, meaning the swarm still considers it a candidate for connection.
* Example:

```js
if (peerInfo.prioritized) console.log('high-priority peer')
```

#### `peerInfo.ban(banStatus = false)` [#peerinfobanbanstatus--false]

[API definition on GitHub](https://github.com/holepunchto/hyperswarm/blob/v4.17.2/lib/peer-info.js#L109)

* Signature: `peerInfo.ban(banStatus = false)`
* Parameters:
  * `banStatus`: `true` to ban the peer or `false` to unban it.
* Returns: Nothing. Updates whether the swarm should avoid future reconnect attempts.
* Example:

```js
peerInfo.ban(true)
```

Banning prevents future reconnection attempts, but it does not close an already-open connection.

## See also [#see-also]

* [Connect to many peers by topic with Hyperswarm](/p2p/how-to/connect-to-peers/connect-to-many-peers-by-topic-with-hyperswarm)—broader topic-based discovery walkthrough.
* [Connect two peers by key with HyperDHT](/p2p/how-to/connect-to-peers/connect-two-peers-by-key-with-hyperdht)—direct one-to-one connections without topic discovery.
* [HyperDHT](/p2p/reference/building-blocks/hyperdht)—lower-level DHT and hole-punching layer beneath Hyperswarm.
* [Secretstream](/p2p/reference/helpers/secretstream)—the encrypted stream type that Hyperswarm connections expose.
* [Protomux](/p2p/reference/helpers/protomux)—multiplex multiple protocols across one Hyperswarm connection.
* [Corestore](/p2p/reference/helpers/corestore)—pass swarm connections directly to `store.replicate()` to co-replicate all managed cores.
* [ble-swarm](/bare/reference/bare/modules/ble-swarm)—Bluetooth LE transport shaped like Hyperswarm, for peers with no shared internet path. Its connections are the same `NoiseSecretStream`s; [Bluetooth in Bare](/bare/explanation/bluetooth#security) explains where it fits.
