npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

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.

About

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 🙏

© 2026 – Pkg Stats / Ryan Hefner

civildefense.io

v0.0.51

Published

Browser app to safely share live sightings on a map.

Readme

CivilDefense.io

The App

CivilDefense.io lets you report an immediate concern to the public by tapping its location on the map. The locations are shared over anonymous p2p with other users in your area, then fade away over 10 minutes. There is no login and no global tracking of your Internet address or physical location.

See here.

FIXME: The app is not ready public use just yet.

The Implementation

Some apps of this type have been removed from mobile app stores, while others remain. CivilDefense.io is implemented as a web page, so that it does not have to rely on an app store.

Additionally, the source code is available right here so that a mirror can be hosted by anyone.

Finally, all mirrors share the same data through peer-to-peer connections, so all reporting is automatically shared among all mirrors, regardless of which mirror the user entered through. There is no central database to be taken down.

The Bigger Project

YZ.social ("wise social") is building a secure, free, and open source, peer-to-peer network for a new class of applications. The YZ network has no servers, no central database, no single point of failure. It is a true, fully decentralized network constructed, controlled and owned by its users. CivilDefense.io is the first application built on the YZ network.

Running a Portal

Visitors enter network through a "portal", which serves the web pages and connects the user to other peers in the network. Anyone can run such a portal.

A local, private copy for development can be run with:

git clone https://github.com/YZ-social/civildefense.io.git; cd Yz.social
npm install
npm run local # Now visit http://localhost:3000

Sharing

This network can only be reached through http://localhost:3000. To run a network that is connected to the world-wide YZ network, instead to

npm run shared

To allow people visit the page from another device, the server must use https. This is usually done with a front end (aka reverse proxy server) such as nginx or OpenResty, and most commercial setups already operate this way. For example, at civildefense.io and our own mirror at ki1r0y.com, nginx handles https connection handshake and certificate (tcp inbound 443), and passes the request to NodeJS running on port 3000.

What It Does

The application server does a few things:

  1. It serves the static client files - i.e., the web page.
  2. It launches 2 or more separate NodeJS processes, each with an a network node just like the one that is run in the browser when someone visits the site. These "portal nodes" allow web visitors to connect to the network. If the box has 6 logical cores or more, it lauches nCores/2 nodes. These will each make outgoing UDP Webrtc connections for each node that connects to them on high-numbered ports. The only difference between npm run local and npm run shared is that with shared, the first portal node connects to a portal node at https://civildefense.io. All remaning portal nodes connect to that one.
  3. It provides a means of connecting to the p2p network. Specifically, it provides post endpoints that deliver Webrtc connection information to the portal nodes. The server passes this info to the requested node process via NodeJS InterProcess Communication (IPC).
  4. It runs a TURN relay (within the web server process). The TURN server listens for setup requests incoming on udp or tcp on 3478. (We do not currently use (D)TLS, which would be 5349.) Additionally, the actual relay traffic happens on incoming udp ports 49152 - 65535.

Building Your Own

This is all done with a very minimal ExpressJS server. The one we provide is in app.js. If you already have such a server set up, you can just:

  1. Add or link public/ to the directory of static client files already being served. E.g.,
  • If you want to serve the static client files from an nginx front end, you can specify root path_to_yz.social_directory/public; in your nginx.conf.
  • If you want to serve the static client files from an existing ExpressJS app server, you can specify app.use(express.static(path_to_yz.social_directory/public));
  1. Fork one or more portal nodes. Our app.js does this with:
import cluster from 'node:cluster';
if (cluster.isPrimary) {
  for (let i = 0; i < nPortals; i++) cluster.fork();
  ...
} else {
  const portalNode = await import('@yz-social/kdht/portal');
  portalNode.setup({});
}
  1. Serve some endpoints so that visitors to your page can find and connect with one of the portal nodes you forked. Our app.js does this with:
if (cluster.isPrimary) {
  for (let i = 0; i < nPortals; i++) cluster.fork();
  const portalServer = await import('@yz-social/kdht/router');
  app.use('/kdht', portalServer.router);
  ...
}
  1. Run a TURN relay. The portal nodes and visitors to your web page are automatically configured to expect a relay at the default STUN/TURN port (3478). The @yz-social/kdht/router imported in step 3 does this automatically.