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

devscan

v1.0.0

Published

Find every developer web server on your local network in one command - and see what your own machine is exposing.

Readme

devscan

Find every dev server on your LAN — starting with your own.

Most scanners point outward. This one starts with you.

devscan --me     # what is my laptop exposing to this wifi right now?
devscan          # ...and what is the rest of this network exposing?
ENDPOINT               HTTP  STACK              TITLE                          SERVER
--------------------------------------------------------------------------------------
10.0.4.138:8000        200   Python http.server internal dashboard             SimpleHTTP/3.12
10.0.5.123:8501        200   Streamlit          Streamlit                      uvicorn
10.0.6.58:3000         200   Next.js            admin console                  Next.js
10.0.9.26:8000         200   FastAPI/uvicorn    -                              uvicorn
10.0.11.234:9000       403   MinIO              -                              MinIO
10.0.7.207:11434       200   Ollama             -                              -

128 dev endpoints on 90 hosts  |  2250 reachable  |  624 AirPlay (hidden)

Identifies the stack behind each open port — Next.js, Express, FastAPI, Vite, Streamlit, Ollama, MinIO, nginx, Jupyter, Gradio, Flask, Grafana, Elasticsearch. No root. No telemetry. One bash file.

Built after a scan where 86% of the "open ports" turned out to be macOS AirPlay. It knows the difference — and it knows three other ways a port scan lies to you silently. See Four things that make the output trustworthy.

Install

git clone <repo> devscan && cd devscan && ./install.sh

or just drop the single file anywhere on your PATH:

curl -o /usr/local/bin/devscan <raw-url> && chmod +x /usr/local/bin/devscan

Dependencies: nmap (brew install nmap) and curl. Falls back to netcat if nmap is missing. No root required.

Usage

devscan                          # scan the local subnet
devscan --me                     # what am I exposing to this network?
devscan --fast                   # top 14 ports, more workers (~3x faster)
devscan --thorough               # retry harder; use if you suspect missed ports
devscan -s 192.168.1.0/24        # a specific subnet
devscan -p 3000,8000,8080        # specific ports
devscan -j | jq '.services[]'    # JSON out
devscan -o ~/scan                # write txt/csv/json
devscan -a                       # ARP cache only, skip the sweep (fast)
devscan --all-ports              # 1-65535 (slow)

What it does

Four stages, each feeding the next so the expensive work only runs on live hosts:

  1. Host discovery — reads the ARP cache and expands the subnet CIDR.
  2. Liveness sweep — 250-way parallel ping. Cuts an 8190-address /19 down to the hosts that actually answer, in ~35 seconds. ARP-known hosts that stay silent get a cheap TCP liveness probe, so ping-blocking machines aren't lost — without dragging every stale ARP entry into the scan.
  3. Port scan — parallel nmap TCP connect scan across ~41 dev ports, with a live progress meter (hosts done, ports found, ETA).
  4. Identification — one GET / per endpoint, classified into Next.js, Express, FastAPI/uvicorn, Streamlit, Vite, MinIO, nginx, Jupyter, Gradio, Ollama, Flask, Grafana, Elasticsearch, or a router admin panel.

Four things that make the output trustworthy

These are the failure modes that made earlier hand-rolled versions of this scan quietly wrong. They're worth knowing because they'll bite any reimplementation.

macOS AirPlay masquerades as a dev server. Ports 5000 and 7000 are ControlCenter (AirPlay Receiver) on every modern Mac. On a network of 546 Macs that's 318 of 369 open ports — 86% of your results are noise, and they look exactly like a Flask app on 5000. devscan scans them, then reports them separately. --show-airplay if you want them.

--host-timeout silently zeroes your scan. When most ports are filtered rather than closed, each probe waits out its full timeout, so a host easily exceeds a 40s budget and nmap abandons it — recording Status: Timeout and emitting no open ports at all. The scan completes, exits 0, and reports nothing wrong. devscan drops --host-timeout entirely and bounds the individual probes instead (--max-rtt-timeout 900ms), so slow hosts finish rather than get abandoned. It then counts any residual timeouts and warns.

--max-retries 0 silently abandons ports. The obvious cure for #2 is to stop nmap retrying. Do that on lossy wifi and it starts printing giving up on port because retransmission cap hit (0) — once per abandoned port, to stdout, which most wrappers send to /dev/null. Measured on 200 hosts: --max-retries 0 produced dozens of drops, --max-retries 1 produced one. devscan defaults to 1, exposes 0 via --fast, and counts the warnings and tells you rather than under-reporting in silence.

sort -u with restricted keys eats your findings. This looks reasonable:

sort -u -t. -k1,1n -k2,2n -k3,3n -k4,4n endpoints.txt

With -t., the fourth field of 10.7.11.170:8000 is 170:8000, and -k4,4n parses that as 170. Every port on a host therefore shares one sort key, and -u deduplicates on the key, not the line — so a host with four open ports collapses to one. devscan builds an explicit zero-padded key and dedupes on the full line (sort_eps).

And one more, non-obvious: in zsh, for p in $PORTS does not word-split an unquoted scalar the way bash does — you get one iteration with the whole string. devscan is #!/usr/bin/env bash for exactly this reason.

Limitations

  • Dev servers bound to 127.0.0.1 are invisible from the network by design. Vite, Next.js and Rails all default to localhost, so absence here is not evidence nothing is running — it usually means it's bound correctly.
  • ICMP-filtered hosts are only probed if they appear in the ARP cache.
  • Identification is a single unauthenticated GET /. It reads banners; it does not probe paths, guess credentials, or test for vulnerabilities.

Scope

This is an inventory tool. It performs host discovery, a TCP connect scan, and one HTTP GET per open port — the same traffic as opening the page in a browser. It contains no exploitation, credential, or vulnerability-probing behaviour, and none will be added.

Only scan networks you own or have written authorization to assess. Port scanning third-party hosts without permission is unlawful in many jurisdictions, and shared conference, campus, or coworking Wi-Fi is not your network.

License

MIT