Skip to content
minip2p
Esc
navigateopen⌘Jpreview
On this page

Node.js quickstart

Install @minip2p/node, connect to a peer, and measure a Ping RTT.

@minip2p/node requires Node.js 24 or newer and uses ES modules.

Install

mkdir minip2p-quickstart
cd minip2p-quickstart
npm init -y
npm install @minip2p/node

Run two peers

Open two terminals in this directory. In the first, create listener.mjs:

import { Minip2p, generateSecretKey } from "@minip2p/node";

const endpoint = Minip2p.create({
  agentVersion: "my-app/0.1.0",
  secretKey: generateSecretKey(),
  transports: {
    quic: { listen: ["/ip4/127.0.0.1/udp/4001/quic-v1"] },
  },
});

console.log("listening at");
console.log(endpoint.listenAddrs()[0]);

Run it and leave it running:

node listener.mjs

It prints an address like this:

listening at
/ip4/127.0.0.1/udp/4001/quic-v1/p2p/12D3KooW...

Copy the complete address, including /p2p/<peer-id>. In the second terminal, create connect.mjs:

import { Minip2p, generateSecretKey } from "@minip2p/node";

const remoteAddress = process.argv[2];
if (remoteAddress === undefined) {
  throw new Error("pass a peer multiaddress");
}

const endpoint = Minip2p.create({
  agentVersion: "my-app/0.1.0",
  secretKey: generateSecretKey(),
});

try {
  const connected = await endpoint.connectAddr(remoteAddress, {
    timeoutMs: 10_000,
  });
  await endpoint.waitPeerReady(connected.peerId, { timeoutMs: 10_000 });
  const rttMs = await endpoint.ping(connected.peerId, { timeoutMs: 5_000 });

  console.log(`connected over ${connected.path.kind}`);
  console.log(`ping: ${rttMs} ms`);
} finally {
  endpoint.close();
}

Run it with the address from the listener:

node connect.mjs /ip4/127.0.0.1/udp/4001/quic-v1/p2p/12D3KooW...

The second terminal prints output like this:

connected over directDialed
ping: 4 ms

connectAddr returns the first usable path. waitPeerReady then waits for Identify when you want the advertised protocol list before starting protocol work. openStream does not require that wait for a known protocol.

This listener accepts connections only from the same machine. To let a phone or another computer connect, bind a LAN interface instead, such as /ip4/192.168.1.42/udp/4001/quic-v1, and give it the printed address.

generateSecretKey() creates a new peer identity on every run. Load the same secret bytes from protected storage when the peer needs a stable ID.

Keep a service running

A running endpoint keeps the Node.js process alive. Long-running applications should close it during shutdown. See Endpoint lifecycle for signal handling and identity persistence.

Next: Connections and streams or Networking and events.

Last updated on September 21, 2026

Was this page helpful?