# Connect to many peers by topic with Hyperswarm



In [Connect two peers by key with HyperDHT](/p2p/how-to/connect-to-peers/connect-two-peers-by-key-with-hyperdht), two peers connected directly using the first peer's public key.
Hyperswarm helps to discover peers swarming a common topic, and connect to as many of them as possible.
This will become clearer in [Replicate and persist with Hypercore](/p2p/how-to/store-and-replicate/replicate-and-persist-with-hypercore),
but it's the best way to distribute peer-to-peer data structures.

The [Hyperswarm](/p2p/reference/building-blocks/hyperswarm) module provides a higher-level interface over the underlying [HyperDHT](/p2p/reference/building-blocks/hyperdht),
abstracting away the mechanics of establishing and maintaining connections.
Instead, 'join' topics, and the swarm discovers peers automatically. It also handles reconnection in the event of failures.

In [Connect two peers by key with HyperDHT](/p2p/how-to/connect-to-peers/connect-two-peers-by-key-with-hyperdht),
we needed to explicitly indicate which peer was the server and which was the client.
By using Hyperswarm, we create two peers, have them join a common topic, and let the swarm deal with connections.

<Callout type="info">
  **Pear-end logic—start from a boilerplate.** The code in this guide lives in the Bare [worker](/pear/explanation/workers): peer-to-peer logic, no UI. The same worker runs unchanged on desktop, terminal, and mobile—only the shell differs (see [Runtime and languages](/pear/explanation/runtime-and-languages)). Start from a boilerplate in [Start from a template](/p2p/getting-started/from-a-template)—desktop ([`hello-pear-electron`](/p2p/getting-started/from-a-template/start-from-hello-pear-electron)) or terminal ([`hello-pear-bare`](/p2p/getting-started/from-a-template/start-from-hello-pear-bare))—and add this capability on top.
</Callout>

<Callout type="info">
  This guide is a terminal-only walkthrough. For the **desktop equivalent**—the same topic-based discovery wired into an Electron + Bare worker shell—follow the [Getting Started path](/p2p/getting-started), which builds a `pear://` chat app on top of the [`hello-pear-electron` template](/p2p/getting-started/from-a-template/start-from-hello-pear-electron).
</Callout>

## Create the `peer-app` project [#create-the-peer-app-project]

Create the `peer-app` project with the following commands:

```sh example=hyperswarm-chat step=setup
mkdir peer-app
cd peer-app
npm init -y
npm pkg set type="module"
npm install hyperswarm hypercore-crypto b4a bare-process
```

Alter the peer-app/index.js file to the following. Create a single [Hyperswarm](/p2p/reference/building-blocks/hyperswarm) instance (L7). On each `connection` event, track the connection and log incoming data from that peer (L13–L20). Broadcast anything typed on stdin to every open connection (L23–L28). Then join a common topic as both client and server—reusing a topic passed on the command line, or generating a fresh one (L31–L32). The [`discovery.flushed()`](/p2p/reference/building-blocks/hyperswarm#await-discoveryflushed) promise resolves once the topic has been announced to the DHT, at which point the topic is logged for other peers to copy (L35–L37).

```javascript file=<rootDir>/examples/how-to/connect-to-peers/connect-to-many-peers-by-topic-with-hyperswarm/peer-app/index.js title="peer-app/index.js" lineNumbers {7,13-20,23-28,31-32,35-37} skip="example-import"

import Hyperswarm from 'hyperswarm'
import crypto from 'hypercore-crypto'
import b4a from 'b4a'
import process from 'bare-process'

const swarm = new Hyperswarm()
const name = b4a.toString(swarm.keyPair.publicKey, 'hex')
process.once('SIGINT', () => swarm.destroy().then(() => process.exit(0), () => process.exit(0)))

// Keep track of all connections and console.log incoming data
const conns = []
swarm.on('connection', conn => {
  const peer = b4a.toString(conn.remotePublicKey, 'hex')
  console.log('* got a connection from:', peer, '*')
  conns.push(conn)
  conn.once('close', () => conns.splice(conns.indexOf(conn), 1))
  conn.on('data', data => console.log(`${peer}: ${data}`))
  conn.on('error', e => console.log(`Connection error: ${e}`))
})

// Broadcast stdin to all connections
process.stdin.on('data', d => {
  console.log(`${name}: ${d}`)
  for (const conn of conns) {
    conn.write(d)
  }
})

// Join a common topic
const topic = Bare.argv[2] ? b4a.from(Bare.argv[2], 'hex') : crypto.randomBytes(32)
const discovery = swarm.join(topic, { client: true, server: true })

// The flushed promise will resolve when the topic has been fully announced to the DHT
discovery.flushed().then(() => {
  console.log('joined topic:', b4a.toString(topic, 'hex'))
})
```

## Run the swarm [#run-the-swarm]

In one terminal, move one directory up and run `peer-app` with `bare`:

```sh example=hyperswarm-chat step=run process=peer1 expect="joined topic:" capture-topic="joined topic: ([0-9a-f]+)" timeout=45000
bare peer-app
```

This will display the topic. Copy/paste that topic into as many additional terminals as desired:

```sh example=hyperswarm-chat step=run process=peer2 cmd="bare peer-app ${topic}" expect="got a connection from:" timeout=45000
bare peer-app <SUPPLY TOPIC HERE>
```

Each peer will log information about the other connected peers. Start typing into any terminal, and it will be broadcast to all connected peers.

<Callout type="info">
  **Use one [Hyperswarm](/p2p/reference/building-blocks/hyperswarm) instance per application.** A single swarm can join multiple topics and dedups peer connections shared between them. This speeds up connections by reducing [HyperDHT](/p2p/reference/building-blocks/hyperdht) records per topic and simplifies managing the maximum number of connections your app makes.
</Callout>

Connections established here are ephemeral—once both peers go offline the conversation is lost.

## See also [#see-also]

* [Replicate and persist with Hypercore](/p2p/how-to/store-and-replicate/replicate-and-persist-with-hypercore)—persist messages so a reader catches up after the writer disconnects.
* [Peer-to-peer, demystified](/p2p/explanation/peer-to-peer-demystified)—how topic discovery and hole punching work under Hyperswarm.
* [Connect two peers by key with HyperDHT](/p2p/how-to/connect-to-peers/connect-two-peers-by-key-with-hyperdht)—direct one-to-one connection by public key.
* [Hyperswarm reference](/p2p/reference/building-blocks/hyperswarm)—full API for topic joins, connection events, and peer management.
* [HyperDHT reference](/p2p/reference/building-blocks/hyperdht)—the lower-level DHT layer Hyperswarm is built on.
