Building a P2P Online Chat Room using libp2p and JavaScript: A Walkthrough with Code Snippets

In our previous article, we discussed the basics of creating a peer-to-peer (P2P) online chat room using libp2p and JavaScript. In this follow-up, we'll dive deeper into the implementation details and provide some code snippets to help you along the way.

First, let's set up the basic structure of our chat room. We'll use Node.js as the runtime environment and the JavaScript implementation of libp2p, called js-libp2p, to handle the P2P communication.

const Libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const Mplex = require('libp2p-mplex')
const { NOISE } = require('libp2p-noise')
const Secio = require('libp2p-secio')
const PeerId = require('peer-id')
const multiaddr = require('multiaddr')

// Generate a new PeerId
const peerId = await PeerId.create()

// Create a libp2p node
const libp2p = new Libp2p({
  peerId: peerId,
  addresses: {
    listen: ['/ip4/']
  modules: {
    transport: [TCP],
    streamMuxer: [Mplex],
    connEncryption: [NOISE, Secio],

// Start the libp2p node
await libp2p.start()

This sets up the basic structure of our libp2p node, including the transport (TCP), stream multiplexer (Mplex), and connection encryption (NOISE and Secio). Note that we're binding the node to listen on all available IP addresses and on a random port.

Next, we'll need a way for users to connect to the chat room. We can do this by advertising our multiaddress (the combination of our IP address and port) using a peer discovery service such as libp2p-mdns or libp2p-discovery.

const mdns = require('libp2p-mdns')

// Add the mdns peer discovery module

// Get our multiaddress
const ma = libp2p.multiaddrs.toArray().find(ma => ma.includes('ip4'))
console.log('Multiaddress:', ma.toString())

With this code, we're adding the mdns peer discovery module to our libp2p node and printing out the multiaddress to the console. Users can then connect to this address to join the chat room.

Now that we have users connecting to the chat room, we'll need a way for them to send and receive messages. We can do this using the libp2p.handle method to handle incoming messages and the libp2p.dialProtocol method to send messages to other peers.

First, let's start by handling incoming messages. We can use the libp2p.handle method to register a callback function that will be invoked every time a message is received. This callback function will take two arguments, the stream that the message was received on and the message itself.

libp2p.handle('/chat/1.0.0', (protocol, conn) => {
    conn, => {
      // do something with the data
    pull.onEnd(() => {
      // handle the end of the stream

In this example, we're using the pull-stream library to handle the stream of data. The function is used to process the data as it comes in, and the pull.onEnd function is used to handle the end of the stream.

Now that we can handle incoming messages, let's move on to sending messages. We can use the libp2p.dialProtocol method to open a stream to a specific peer and send a message.

libp2p.dialProtocol(peerId, '/chat/1.0.0', (err, conn) => {
  if (err) {
    throw err
    pull.values(['Hello, Peer!']),

In this example, we're using the pull-stream library to send a message to the specified peer. The pull.values function is used to create a stream of data, in this case, the message "Hello, Peer!" and the conn argument is used to send the message to the specified peer.

With these two pieces of functionality in place, we now have a basic p2p chat room set up. Users can connect to the chat room, send and receive messages, and disconnect at any time. There are many ways to improve and expand upon this basic setup, such as adding encryption, handling errors, and improving the user interface. But with libp2p and javascript, building a p2p chat room is easy and straightforward.

So, that's it, you've now built a basic p2p chat room using libp2p and javascript. With some added functionality and a bit of styling, you'll have a fully functional and secure chat room ready to go in no time!