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

@simplified-org/tunnel

v1.1.0

Published

CLI to expose a local port via simplified-org.com with one command

Readme

simplified-tunnel

Portable tunneling stack built on FRP, consisting of:

  • FRP server (frps): terminates tunnels and routes subdomains to clients.
  • Tunnel Manager API + admin UI (src/): hands out subdomains, tracks activity, exposes WebSocket updates, and serves a localhost-only dashboard.
  • CLI (simplified): one-command client that requests a tunnel and runs frpc for you.

Use this README to self-host the full stack (Docker or bare metal), understand the architecture, and see operational quirks.


How the system behaves

  1. A client (via CLI or HTTP) asks the Tunnel Manager for a subdomain. If none is provided, the manager generates a memorable adjective-noun (optionally with numeric suffix).
  2. The manager returns FRP connection info plus the public URL (https://<subdomain>.<FRP_DOMAIN>).
  3. The client starts frpc to connect to the FRP server using the shared token.
  4. FRP server (frps) accepts the tunnel and vhosts HTTP traffic for that subdomain to the client’s local port.
  5. All requests are logged; admin dashboard/WebSocket streams live stats and logs (localhost-only by default).

Repo layout

  • Dockerfile, start.sh, frps.ini.template, docker-compose.yml – FRP server container + compose with API.
  • bin/simplified.js, lib/* – CLI entrypoint, tunnel API client, frpc downloader/runner.
  • src/ – Tunnel Manager API + admin UI.
    • server/index.js HTTP + WebSocket server, middleware, admin gating.
    • server/api.js REST routes.
    • server/tunnelManager.js in-memory + file-backed tunnel state, history, WebSocket broadcasting.
    • server/logger.js request/tunnel logging to file + buffer + WS.
    • server/randomWords.js subdomain generation/validation.
    • admin/ static dashboard (served locally).
    • data/ runtime state/logs (gitignored).
  • test/webapp – simple sample webapp + FRP binaries for local testing.

Prerequisites for self-hosting

  • A domain; add a wildcard DNS record *.your-domain pointing to the host running frps (DNS-only/proxied off).
  • Open ports: 80 (HTTP vhost) and 7000 (FRP control).
  • A shared FRP token (FRP_TOKEN).
  • Node.js 18+ if running the API/CLI directly; Docker if containerizing.
  • TLS termination handled externally (e.g., Cloudflare “Full” mode) — this stack serves HTTP only.

Option A: Docker Compose (FRP server + Tunnel Manager)

cp docker-compose.yml docker-compose.local.yml
# edit env values in the file or export FRP_TOKEN/FRP_SERVER_ADDR etc.
docker compose -f docker-compose.local.yml up --build

Services:

  • frps (ports 80, 7000) built from the Dockerfile; requires FRP_DOMAIN, FRP_BIND_PORT, FRP_HTTP_PORT, FRP_TOKEN, optional FRP_MAX_POOL.
  • api (port 4000) runs /src with npm install && npm start; set ADMIN_HOST=0.0.0.0 only if you intend to expose the dashboard and secure it yourself (defaults to localhost when run bare).

Recommended extras:

  • Mount ./src/data as a volume to keep tunnel/log/history data across restarts.
  • Set FRP_SERVER_ADDR to the public IP/DNS of the frps host (defaults to 34.227.103.55 in compose; change this).

Option B: Docker only (FRP server)

Build and run the FRP server container:

docker build -t simplified-tunnel-frps .
docker run --rm -p 80:80 -p 7000:7000 \
  -e FRP_DOMAIN=your-domain.com \
  -e FRP_BIND_PORT=7000 \
  -e FRP_HTTP_PORT=80 \
  -e FRP_TOKEN=your-token \
  -e FRP_MAX_POOL=200 \
  simplified-tunnel-frps

Then run the Tunnel Manager separately (Node or another container) pointed at this FRP endpoint.


Option C: Bare metal

FRP server

export FRP_DOMAIN=your-domain.com
export FRP_BIND_PORT=7000
export FRP_HTTP_PORT=80
export FRP_TOKEN=your-token
# place a compatible frps binary in PATH or alongside start.sh
./start.sh

Tunnel Manager API + admin

cd src
npm install
TUNNEL_MANAGER_PORT=4000 \
ADMIN_HOST=127.0.0.1 \
FRP_DOMAIN=your-domain.com \
FRP_SERVER_ADDR=<frps-host> \
FRP_BIND_PORT=7000 \
FRP_TOKEN=your-token \
npm start

Admin dashboard lives at http://127.0.0.1:4000/admin (localhost-only). APIs under /api.


CLI (client) usage against your deployment

npm install -g simplified
SIMPLIFIED_API_BASE=http://<api-host>:4000 simplified --port 3000
# optional: --subdomain my-site
  • Downloads frpc from GitHub releases (cached at ~/.simplified/frpc).
  • Supported platforms: macOS (arm64/amd64), Linux (arm64/amd64), Windows (amd64/arm64).

Configuration reference

FRP server (start.sh / Dockerfile / compose)

  • Required: FRP_DOMAIN, FRP_BIND_PORT, FRP_HTTP_PORT, FRP_TOKEN
  • Optional: FRP_MAX_POOL (default 200), FRPS_BIN (custom binary path)

Tunnel Manager (src/config.js)

  • TUNNEL_MANAGER_PORT (default 4000)
  • ADMIN_HOST (default 127.0.0.1 — set to 0.0.0.0 only when you secure access)
  • FRP_DOMAIN (default simplified-org.com)
  • FRP_SERVER_ADDR (default localhost)
  • FRP_BIND_PORT (default 7000)
  • FRP_TOKEN (default supersecret)
  • MAX_TUNNELS_PER_USER (default 5)
  • TUNNEL_TIMEOUT (default 24h, ms)
  • Data files live in src/data: tunnels.json, history.json, requests.log (gitignored).

CLI

  • SIMPLIFIED_API_BASE overrides the API URL (defaults to https://api.simplified-org.com).

DNS/TLS:

  • Create wildcard A record *.<FRP_DOMAIN> to the frps host.
  • TLS terminates at your DNS/CDN; frps serves HTTP only.

Code architecture and flow

  • CLI
    • bin/simplified.js: parses flags, calls tunnel API, ensures frpc, spawns it.
    • lib/api.js: POST /api/tunnels, handles errors.
    • lib/downloader.js: downloads/extracts frpc (v0.61.0) per OS/arch into ~/.simplified.
    • lib/tunnel.js: spawns frpc http -s <addr> -P <port> -l <local> --sd <subdomain> -t <token>.
  • Tunnel Manager (src/server)
    • index.js: Express + WS server; logs every request; gates admin routes to localhost; serves /admin; health/root endpoints.
    • api.js: REST routes for tunnel CRUD, availability checks, suggestions, stats, admin logs/history/config.
    • tunnelManager.js: in-memory map + JSON persistence; random subdomains; conflict resolution; TTL cleanup; WebSocket broadcasts of tunnels/stats; modes (production vs local).
    • logger.js: request/tunnel log levels, file append, in-memory buffer, WS fanout, log filtering/cleanup APIs.
    • randomWords.js: adjective/noun lists, suffixes, validation and alternative generation.
    • config.js: env parsing and defaults.
    • admin/: static dashboard (dark theme) consuming /ws for live updates.
  • FRP server
    • start.sh: validates env, renders frps.ini from template via envsubst, execs frps.
    • Dockerfile: alpine base, downloads FRP frps (default v0.52.3) for detected arch, runs as non-root.

Quirks and operational notes

  • Admin access is localhost-only in code. In docker-compose.yml, ADMIN_HOST is set to 0.0.0.0; you must secure that port yourself (firewall, auth, VPN).
  • Data persistence: src/data is not volume-mounted by default in compose—mount it to avoid losing tunnels/logs/history.
  • FRP versions differ: container pulls frps v0.52.3 while the CLI fetches frpc v0.61.0; align versions if you see protocol warnings.
  • Stats persistence is throttled (writes every 10 requests) to reduce disk I/O.
  • Tunnel expiry defaults to 24h; expired tunnels are removed and added to history.
  • Subdomain suggestions reserve names like admin, api, localhost; conflicts return alternatives.
  • HTTPS termination is out of scope; keep DNS/CDN in “DNS only” (no orange cloud) unless you handle TLS separately.
  • CLI cache location: ~/.simplified/frpc; removal is manual.
  • WebSocket and admin endpoints reject non-local IPs; log entries include IP/User-Agent for auditing.
  • Compose uses a hardcoded example IP 34.227.103.55 for FRP_SERVER_ADDR; change it to your host.

How to propose improvements

Ideas based on current code paths:

  • Align frps/frpc versions and make the version configurable in both Dockerfile and CLI.
  • Add auth to the admin dashboard and optionally allow remote access with proper protection.
  • Persist data to a real store (SQLite/Postgres) and run migrations instead of JSON files.
  • Add rate limits / per-IP quotas in requestTunnel to prevent abuse.
  • Expose metrics (Prometheus) and health for frps alongside the API health check.
  • Support HTTPS termination (LetsEncrypt/ACME) or behind-proxy documentation.
  • Provide official images for the API (not just compose-on-the-fly).
  • Add integration tests that spin up frps + API + sample frpc to validate end-to-end.

Testing the sample webapp locally

cd test/webapp/backend
npm install
npm start   # serves http://localhost:3000

Use the CLI with --port 3000 against your running manager + frps to publish it.


Uninstalling the CLI

npm uninstall -g simplified
rm -rf ~/.simplified/frpc