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

portless-proxy

v1.0.2

Published

Local dev reverse proxy — access services via subdomains instead of port numbers

Readme

Portless Proxy

Local dev reverse proxy — access your services via <name>.localhost subdomains instead of tracking port numbers.

http://api.localhost  ->  your api server on some random port
http://web.localhost  ->  your web server on some random port
http://admin.localhost  ->  your admin server on some random port

Inspired by Vercel's portless project.

Install

npm install -g portless-proxy

Or use with npx:

npx portless-proxy
npx portless api

Quick Start

1. Create a config file in your project root:

portless init

This creates portless.json:

{
  "proxyPort": 80,
  "proxyPortRange": [8001, 8099],
  "services": {
    "web": {
      "cwd": "./packages/web",
      "command": "npm start",
      "env": { "PORT": "{port}" }
    },
    "api": {
      "cwd": "./packages/api",
      "command": "npm start",
      "env": { "PORT": "{port}" }
    }
  }
}

Edit it to match your project.

2. Start the proxy (requires port 80):

portless-proxy

3. Start services in another terminal:

portless api          # start one service
portless all          # start all services

4. Open your browser:

http://api.localhost
http://web.localhost

Configuration

portless.json in your project root:

| Field | Default | Description | |-------|---------|-------------| | proxyPort | 80 | Port for the default (non-namespaced) proxy | | proxyPortRange | [8001, 8099] | Port range for namespaced proxies | | services | — | Map of service name to service config |

Service config

Each service entry:

| Field | Default | Description | |-------|---------|-------------| | cwd | — | Working directory for the service (relative to portless.json) | | command | — | Shell command to start the service | | env | { "PORT": "{port}" } | Environment variables to set. Supports placeholders. |

Placeholders

Use these in env values:

| Placeholder | Replaced with | |-------------|---------------| | {port} | The auto-assigned port for this service | | {proxyPort} | The proxy port (useful for constructing URLs) | | {name} | The service name |

Examples

Node.js services:

{
  "services": {
    "api": {
      "cwd": "./services/api",
      "command": "npm start",
      "env": { "PORT": "{port}" }
    }
  }
}

ASP.NET services:

{
  "services": {
    "api": {
      "cwd": "./src/MyApp.Api",
      "command": "dotnet run --no-launch-profile",
      "env": {
        "ASPNETCORE_URLS": "http://localhost:{port}",
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Python / Flask:

{
  "services": {
    "api": {
      "cwd": "./backend",
      "command": "flask run",
      "env": {
        "FLASK_RUN_PORT": "{port}",
        "FLASK_ENV": "development"
      }
    }
  }
}

Namespaces — Run Multiple Branches in Parallel

Namespaces let you run multiple isolated environments side-by-side. Each namespace gets its own proxy on its own port, so two branches of the same service don't collide.

# Terminal group A — working on bug-123
portless-proxy bug-123                  # auto-picks a port, e.g. 8001
portless --ns bug-123 api              # starts api behind that proxy

# Terminal group B — working on feat-456
portless-proxy feat-456                 # auto-picks a port, e.g. 8002
portless --ns feat-456 api             # starts api behind this proxy

# Access in browser
# http://api.localhost:8001   (bug-123)
# http://api.localhost:8002   (feat-456)

Each namespace:

  • Gets its own proxy on an auto-assigned port from proxyPortRange
  • Writes a port file to .portless/<namespace>.json so portless can discover it
  • Cleans up on shutdown

List services for a specific namespace:

portless --ns bug-123 list

Service Discovery

When launching a service, portless injects environment variables for every service defined in your config:

PORTLESS_URL_API=http://api.localhost:80
PORTLESS_URL_WEB=http://web.localhost:80

Pattern: PORTLESS_URL_<UPPERCASED_NAME>. These include the correct proxy port, so inter-service calls work in both default and namespaced modes.

Your services can read these to call each other without hardcoding URLs.

CLI Reference

portless-proxy [namespace]

Start the reverse proxy.

  • Without namespace: binds to proxyPort (default 80)
  • With namespace: auto-picks a port from proxyPortRange, writes .portless/<namespace>.json

portless [--ns <namespace>] <service|all>

Start one or all services.

  • --ns <namespace>: target a namespaced proxy instead of the default

portless [--ns <namespace>] list

Show active services and their routes.

portless init

Create a template portless.json in the current directory.

How It Works

Browser  ->  http://api.localhost  ->  proxy (:80)  ->  your service (:4xxx)
             http://web.localhost  ----^                 your service (:4xxx)
  1. portless-proxy starts an HTTP reverse proxy that routes requests by subdomain
  2. portless <name> picks a free port (4000–4999), registers with the proxy via an internal API, then spawns your service command with the port injected via env vars
  3. The proxy forwards api.localhost traffic to whichever port the api service registered on
  4. On shutdown, services unregister and child processes are killed

The proxy exposes these internal endpoints on localhost / 127.0.0.1:

  • POST /_register{ "name": "api", "port": 4001 }
  • POST /_unregister{ "name": "api" }
  • GET /_routes — returns JSON map of active routes

WebSocket connections are supported and proxied automatically.

License

MIT