npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details


  • User packages



Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.


Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2020 – Pkg Stats / Ryan Hefner




JavaScript implementation of circuit/switch relaying









Discourse posts Dependency Status js-standard-style

Node.js implementation of the Circuit module that libp2p uses, which implements the interface-connection interface for dial/listen.

libp2p-circuit implements the circuit-relay mechanism that allows nodes that don't speak the same protocol to communicate using a third relay node.

Note: This module uses pull-streams for all stream based interfaces.


circuit-relaying uses additional nodes in order to transfer traffic between two otherwise unreachable nodes. This allows nodes that don't speak the same protocols or are running in limited environments, e.g. browsers and IoT devices, to communicate, which would otherwise be impossible given the fact that for example browsers don't have any socket support and as such cannot be directly dialed.

The use of circuit-relaying is not limited to routing traffic between browser nodes, other uses include:

  • routing traffic between private nets and circumventing NAT layers
  • route mangling for better privacy (matreshka/shallot dialing).

    It's also possible to use it for clients that implement exotic transports such as devices that only have bluetooth radios to be reachable over bluetooth enabled relays and become full p2p nodes.

libp2p-circuit and IPFS

Prior to libp2p-circuit there was a rift in the IPFS network, were IPFS nodes could only access content from nodes that speak the same protocol, for example TCP only nodes could only dial to other TCP only nodes, same for any other protocol combination. In practice, this limitation was most visible in JS-IPFS browser nodes, since they can only dial out but not be dialed in over WebRTC or WebSockets, hence any content that the browser node held was not reachable by the rest of the network even through it was announced on the DHT. Non browser IPFS nodes would usually speak more than one protocol such as TCP, WebSockets and/or WebRTC, this made the problem less severe outside of the browser. libp2p-circuit solves this problem completely, as long as there are relay nodes capable of routing traffic between those nodes their content should be available to the rest of the IPFS network.

Lead Maintainer

Jacob Heun

Table of Contents



> npm i libp2p-circuit



Create dialer/listener

const Circuit = require('libp2p-circuit')
const multiaddr = require('multiaddr')
const pull = require('pull-stream')

const mh1 = multiaddr('/p2p-circuit/ipfs/QmHash') // dial /ipfs/QmHash over any circuit

const circuit = new Circuit(swarmInstance, options) // pass swarm instance and options

const listener = circuit.createListener(mh1, (connection) => {
  console.log('new connection opened')

listener.listen(() => {

    pull.onEnd(() => {


new connection opened

Create relay

const Relay = require('libp2p-circuit').Relay

const relay = new Relay(options)

relay.mount(swarmInstance) // start relaying traffic

This module uses pull-streams

We expose a streaming interface based on pull-streams, rather then on the Node.js core streams implementation (aka Node.js streams). pull-streams offers us a better mechanism for error handling and flow control guarantees. If you would like to know more about why we did this, see the discussion at this issue.

You can learn more about pull-streams at:

Converting pull-streams to Node.js Streams

If you are a Node.js streams user, you can convert a pull-stream to a Node.js stream using the module pull-stream-to-stream, giving you an instance of a Node.js stream that is linked to the pull-stream. For example:

const pullToStream = require('pull-stream-to-stream')

const nodeStreamInstance = pullToStream(pullStreamInstance)
// nodeStreamInstance is an instance of a Node.js Stream

To learn more about this utility, visit


libp2p-circuit accepts Circuit addresses for both IPFS and non IPFS encapsulated addresses, i.e:


Both for dialing and listening.

Implementation rational

This module is not a transport, however it implements interface-transport interface in order to allow circuit to be plugged with libp2p-swarm. The rational behind it is that, libp2p-circuit has a dial and listen flow, which fits nicely with other transports, moreover, it requires the raw connection to be encrypted and muxed just as a regular transport's connection does. All in all, interface-transport ended up being the correct level of abstraction for circuit, as well as allowed us to reuse existing integration points in libp2p-swarm and libp2p without adding any ad-hoc logic. All parts of interface-transport are used, including .getAddr which returns a list of /p2p-circuit addresses that circuit is currently listening.

libp2p                                                                                  libp2p-circuit (transport)
+-------------------------------------------------+                                     +--------------------------+
|        +---------------------------------+      |                                     |                          |
|        |                                 |      |                                     |   +------------------+   |
|        |                                 |      |  circuit-relay listens for the HOP  |   |                  |   |
|        |           libp2p-swarm          <------------------------------------------------|  circuit-relay   |   |
|        |                                 |      |  message to handle incomming relay  |   |                  |   |
|        |                                 |      |  requests from other nodes          |   +------------------+   |
|        +---------------------------------+      |                                     |                          |
|         ^     ^   ^  ^   ^           ^          |                                     |   +------------------+   |
|         |     |   |  |   |           |          |                                     |   | +-------------+  |   |
|         |     |   |  |   |           |          |  dialer uses libp2p-swarm to dial   |   | |             |  |   |
|         |     |   |  +---------------------------------------------------------------------->   dialer    |  |   |
|         |     | transports           |          |  to a circuit-relay node using the  |   | |             |  |   |
|         |     |   |      |           |          |  HOP message                        |   | +-------------+  |   |
|         |     |   |      |           |          |                                     |   |                  |   |
|         v     v   |      v           v          |                                     |   |                  |   |
|+------------------|----------------------------+|                                     |   |  +-------------+ |   |
||           |      |    |      |                ||                                     |   |  |             | |   |
||libp2p-tcp |libp2p-ws  | .... |libp2p-circuit  ||  listener handles STOP messages from|   |  | listener    | |   |
||           |      +-------------------------------------------------------------------------->             | |   |
||           |           |      |plugs in just   ||  circuit-relay nodes                |   |  +-------------+ |   |
||           |           |      |as any other    ||                                     |   |                  |   |
||           |           |      |transport       ||                                     |   +------------------+   |
|+-----------------------------------------------+|                                     |                          |
+-------------------------------------------------+                                     +--------------------------+


Contributions are welcome! The libp2p implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out:

Please be aware that all interactions related to libp2p are subject to the IPFS Code of Conduct.

Small note: If editing the README, please conform to the standard-readme specification.


MIT © 2017 Protocol Labs