Bug Fixes
- spawn ENOENT: Use
/bin/sh -cfor command execution so shell scripts and version-manager shims (nvm, fnm, mise) are resolved correctly. Prependnode_modules/.bintoPATHso local project binaries (e.g.next,vite) are found without a global install. (#21, #29) - sudo state directory permissions: System state directory (
/tmp/portless) now uses world-writable + sticky-bit permissions (1777) so non-root processes can register routes after a sudo proxy start. Route and state files created under sudo are chowned back to the real user. (#16) - duplicate route names:
addRoutenow checks for an existing live route and throwsRouteConflictErrorif the hostname is already registered by a running process. Use--forceto override. (#38) - TLS SHA-1 rejection: Force SHA-256 for all CA and server certificate generation. Detect and regenerate existing SHA-1 certificates automatically. Uses the
opensslCLI for signature algorithm checks to maintain compatibility with Node.js < 24.9. (#36) - per-hostname certs for
.localhostsubdomains: Issue a per-hostname certificate with an exact SAN for every.localhostsubdomain (including single-level likemyapp.localhost).*.localhostwildcard certs are invalid because.localhostis a reserved TLD per RFC 2606 section 2. (#18) - terminal left in raw mode: Reset
stdin.setRawMode(false)on process exit so the terminal is not left in raw mode after SIGINT. (#51)
New Features
- proxy loop detection: Detect forwarding loops (e.g. a Vite dev server proxying back through portless without
changeOrigin: true) using theX-Portless-Hopsheader. Respond with508 Loop Detectedand a message explaining the fix. Also detects loops on WebSocket upgrades. (#48, #52) --forceflag: Override a route registered by another process withportless <name> --force <cmd>.
Install
npm i -g portlessContributors
Thanks to @dpeek, @nyosegawa, and @susanforme for their contributions!