mrkeyoor.com_
Wed 02 Sept 16:55 UTC
Dev Toolsevaluationupdated 02 Sept 2026

portless review

Portless replaces changing local port numbers with stable names such as https://api.myapp.localhost. It runs a local reverse proxy, starts development servers on free ports, and keeps URLs predictable across monorepos and Git worktrees.

trackingstars / 7d
Verdict

Our Portless run installed 1,527 packages and used 1,061 MB, then all 931 executed tests passed in 83 seconds. That is a strong result for teams whose local stack has enough apps, worktrees, or OAuth callbacks to justify a machine-level proxy. Skip it when a fixed port file is sufficient or corporate policy blocks local CA and administrator changes.

We ran it

Lab card: what happened when we ran portlessScreenshot of portless (portless.sh)
Install✓ · 51s1527 packages · 1061 MB
Build✓ · 45s
Tests✓ · 83s931 passed · 0 failed · 3 skipped of 934 (vitest)
Repo196 files~31,661 lines of source · 2.2 MB · 2 CI workflows · tests dir

Answers from our run

Does portless build from source?

Dependencies installed in 51 seconds (1527 packages), and the build succeeded in 45 seconds. We cloned commit 1ad573b into a clean Debian container with 3 CPUs and no project-specific setup.

Do portless's tests pass?

Yes: 931 of 934 passed when we ran the project's own test command (vitest). Some failures need services or credentials a bare container does not have.

Who should not use portless?

Developers on locked-down machines where a tool cannot trust a local CA, edit hosts entries, or obtain administrator rights for port 443.

What are the alternatives to portless?

Caddy, Traefik, puma-dev. Our Portless run installed 1,527 packages and used 1,061 MB, then all 931 executed tests passed in 83 seconds.

Setup3/5One npm install, followed by CA trust and privileged port setup
Docs5/5Detailed framework, monorepo, TLS, LAN, service, and cleanup notes
Community4/511,546 stars with source and issue activity through August 2026
Maturity4/5931 tests passed, though pre-1.0 state and crash reports remain

Who it’s for

Web teams running several local apps that are tired of remembering which service took which port.
Monorepo developers who want package names discovered and routed without maintaining a proxy file by hand.
Engineers using Git worktrees or coding agents that need a distinct, predictable URL for each checkout.
Teams testing HTTPS, subdomains, cookies, WebSockets, or OAuth callbacks before deployment.

Who it’s NOT for

Developers on locked-down machines where a tool cannot trust a local CA, edit hosts entries, or obtain administrator rights for port 443.
Docker-first teams expecting Compose discovery: issue #110 still requests direct Docker Compose support, and issue #399 reports that loopback-only non-LAN binding blocks host-gateway clients.
Projects whose dev script is a compound shell command, starts with environment assignments, delegates to another script, or uses unclassified runner flags: the README says automatic port injection leaves those shapes alone.
IDE users who routinely force-kill the whole process tree and need route state to be crash-safe: open issue #382 reports that an interrupted write can corrupt or empty routes.json.
Teams that require a stable configuration format across upgrades: the README labels Portless pre-1.0 and warns that the state format may change between releases.

Setup reality

Our sandbox installed 1,527 pnpm packages in 51 seconds and used 1,061 MB on disk. The build passed in 45 seconds. Tests passed in 83 seconds: Vitest reported 931 passed, 0 failed, and 3 skipped out of 934. The 2.2 MB checkout had 196 files and about 31,661 source lines.

Repository development now calls for Node.js 24+ and pnpm 11, while ordinary use can start with a global npm install. The first HTTPS run creates a local CA, adds it to the trust store, and tries to bind port 443, which can trigger sudo or an administrator prompt. Local use needs no hosted credentials.

State lives under the user's .portless directory, and custom hostnames may add entries to the hosts file. Startup services run through launchd, systemd, or Task Scheduler with elevated rights. LAN sharing on Linux also needs avahi-utils; Tailscale and ngrok modes require their own installed and authenticated CLIs.

Ports 4000 through 4999 become stable local names

Portless starts each application on a free port between 4000 and 4999, then routes a name such as https://api.myapp.localhost to it. The application receives PORT, HOST, and PORTLESS_URL variables, while the browser and teammates use the memorable address. That removes port collisions from daily conversation and gives local cookies, redirects, and WebSocket clients a hostname that survives restarts.

Framework handling goes beyond setting 1 environment variable. Portless injects port and host flags for Vite, Astro, Angular, Expo, React Native, and other servers that ignore PORT. A monorepo can start all workspace packages with dev scripts, and Git worktrees receive a branch-derived subdomain. That is particularly useful for parallel agents, since 2 checkouts can stay open without sharing one callback URL.

Port 443 requires local trust and often administrator rights

HTTPS and HTTP/2 are enabled by default on port 443. On the first run, Portless creates a local certificate authority, installs it in the operating system trust store, and may request sudo on macOS or Linux. Plain HTTP uses port 80, while an unprivileged custom port avoids sudo at the cost of keeping a port number in the URL.

Those changes are visible and reversible, but they belong to the whole machine. State is stored under the user's .portless directory, route hostnames may be written to the hosts file, and the clean command removes the state, trust entry, and managed hosts block. A startup service can be installed through launchd, systemd, or Windows Task Scheduler. That service can run with root or SYSTEM rights, so teams should treat installation as workstation configuration rather than a package-script detail.

What happened when we ran it

Our sandbox installed commit 1ad573b in 51 seconds. Pnpm added 1,527 packages and the installed tree occupied 1,061 MB. The build then completed successfully in 45 seconds. The repository itself had 196 files, about 31,661 lines of source, and a 2.2 MB checkout.

Vitest finished in 83 seconds with 931 passed, 0 failed, and 3 skipped out of 934. That is a complete passing result for the tests the project exposed in our fresh environment. The repository had a tests directory and 2 CI workflow files, which matches the unusually detailed edge-case coverage visible in its documentation.

Our test method used an unprivileged Debian container with 3 CPUs, 8 GB of RAM, Node.js 22, and no secrets. Install, build, and tests all succeeded there at the measured commit. The current development section now asks contributors to use Node.js 24+ and pnpm 11, so the older successful runtime is evidence about our commit, not a promise that future releases support Node.js 22.

Version 0.15.6 leaves complex package scripts alone

Version 0.15.6 improved flag injection through supported package-manager scripts, but classification remains intentionally conservative. Compound commands, trailing comments, option terminators, environment prefixes, delegated scripts, and runner flags before the script name keep their own ports. This avoids breaking commands Portless cannot parse safely. It also means a project with an elaborate dev wrapper may need an explicit appPort or a simpler script dedicated to the server.

Default .localhost names work in most browsers, while Safari may need a hosts sync. Google and Apple reject .localhost and .test for strict OAuth callbacks, so the README supports a domain you own as a custom multi-segment TLD. Portless writes the required loopback mapping and still binds locally. LAN mode is a separate path that switches to .local and mDNS; on Linux it requires avahi-utils, and a custom TLD cannot be combined with LAN mode today.

121 open items include route-state and Docker gaps

GitHub listed 121 open issues and pull requests on September 2, 2026. Issue 382 describes route-state corruption when an IDE force-kills a process during cleanup and an in-place routes.json write is interrupted. The report says other running routes can disappear with the damaged file. This is a specific failure mode, but IDE stop buttons and process managers make it plausible enough to test before a team puts every local service behind one shared route store.

Docker integration is still partial. Issue 110 requests native Compose support, while issue 399 reports host-gateway refusal because the normal proxy binds only to 127.0.0.1 and ::1. Portless can alias a fixed container port, yet teams expecting label discovery or a non-LAN wildcard bind will find Traefik or Caddy easier to fit.

August 2026 activity supports a careful workstation trial

The last source push was August 29, 2026, and v0.15.6 shipped on August 24. Issue discussion continued into September, so the 121-item combined queue is active rather than abandoned. The release fixed Windows service lifetime, Ctrl+C cleanup, and framework flags, all close to the system-level boundaries that can make a local proxy annoying.

Portless earns a trial when stable HTTPS names solve a repeated problem across several services or worktrees. The 931 passing tests lower the code-risk concern, while 1,061 MB of dependencies and machine-level trust changes raise the setup cost. Start it on one repository, verify HMR, cookies, sibling TLS clients, IDE shutdown, and cleanup, then decide whether replacing port numbers is worth owning the shared proxy.

Alternatives

ProjectWhat it isPick it when
Caddy gh↗A general web server and reverse proxy with automatic local and public HTTPS.pick this instead when you want explicit proxy configuration that can also serve production traffic.
Traefik gh↗A service-aware application proxy commonly configured through container labels and providers.pick this instead when Docker or Kubernetes discovery is the center of the local stack.
puma-devA small local domain manager built around Puma and Rack applications.pick this instead when the team is focused on Ruby web apps and wants a narrower tool.

What people are saying

  1. [github-trending] vercel-labs/portless

Sources

  1. Portless README
  2. Portless v0.15.6 release
  3. Route state corruption report
  4. Docker Compose support request
  5. Docker host-gateway binding report

More dev tools reviews

Magisk · FFmpeg · trippy · 30-Days-Of-Python · fmt · herdr · the whole board →