Changelog
0.13.0
New Features
- OS startup service: New
portless service install,portless service status, andportless service uninstallcommands manage a native startup service for the HTTPS proxy across macOS launchd, Linux systemd, and Windows Task Scheduler. The service starts clean.localhostURLs after reboot, andportless cleanremoves it during cleanup
Bug Fixes
- Tailscale readiness preflight:
--tailscaleand--funnelnow check Tailscale HTTPS and Funnel prerequisites before starting the child process, surfacing actionable errors instead of hanging during registration
0.12.0
New Features
- Tailscale sharing: New
--tailscaleflag shares any portless app over your Tailscale network with zero framework config. Each app is root-mounted on its own Tailscale HTTPS port (443, 8443, 8444, ...) so nobasePathconfiguration is needed. Works as a global flag, per-app flag (portless myapp --tailscale next dev), or env var (PORTLESS_TAILSCALE=1) - Tailscale Funnel: New
--funnelflag exposes apps to the public internet through Tailscale Funnel. Implies--tailscale. Also configurable viaPORTLESS_FUNNEL=1 PORTLESS_TAILSCALE_URLenv var: Child processes receivePORTLESS_TAILSCALE_URLcontaining the Tailscale HTTPS URL so apps can reference their public address- Tailscale URLs in
portless list: The list command now shows tailnet URLs alongside local URLs when Tailscale sharing is active
Improvements
portless prunecleans stale Tailscale registrations: Prune now removes orphanedtailscale serveentries left behind by dead CLI sessionsportless cleanremoves Tailscale serve state: Clean now tears down any Tailscale serve/funnel registrations alongside the usual CA and hosts file cleanup
0.11.1
New Features
portless prunecommand: Safety net to find and kill orphaned dev servers left behind by dead CLI sessions. Reads stale route entries, checks if something is still listening on each port, and terminates the orphan.
Bug Fixes
- Zombie process orphaning on CLI crash: Spawn child processes with
detached:trueon Unix so they get their own process group. Signal handlers now kill the entire group instead of just the immediate child, preventing orphaned dev servers from surviving CLI crashes orkill -9.
0.11.0
New Features
- Zero-arg mode: Run bare
portlessfrom any project directory to auto-discover the dev script frompackage.jsonand start it through the proxy. No arguments, no config required - Multi-app orchestration: In monorepos, bare
portlessauto-discovers workspace packages (pnpm, npm, yarn, bun) and starts all dev scripts concurrently through the proxy. Each package gets a subdomain derived from its npm scope (e.g.@acme/docsbecomesdocs.acme.localhost) - Turborepo integration: When
turbo.jsonis present, portless delegates toturbo run <script>instead of spawning each app individually. Per-appPORT,HOST, andPORTLESS_URLare injected via a lightweight--requireloader so turbo retains dependency ordering and task graph awareness. Setturbo: falsein config to opt out portless.jsonconfig file: Configure app name, script, port, and turbo settings without embedding portless inpackage.jsonscripts. Also supports a"portless"key inpackage.jsonas an inline alternative--scriptflag: Override the default"dev"script for a single invocation (e.g.portless --script start)- Rsbuild support: Auto-inject
--portand--hostCLI flags for Rsbuild dev server
Bug Fixes
- State directory moved to
~/.portless: All proxy state now lives in~/.portlessinstead of/tmp/portless, fixing repeated CA trust prompts on macOS (where/tmpis periodically cleaned) and a symlink local privilege escalation vulnerability - Duplicate macOS CA certificates: Fix
security delete-certificatefailing with "is ambiguous" when multiple portless CA entries had accumulated in the keychain - CA trust marker caching: Cache the CA fingerprint after a successful trust so subsequent proxy starts skip the OS security check and avoid re-triggering the macOS authentication dialog
Improvements
- Auto-trust CA on proxy auto-start: When the proxy is auto-started and the CA is not yet trusted, portless automatically runs trust with proper sudo elevation
- Package manager delegation: Detects pnpm, yarn, bun, or npm and delegates script execution to the correct package manager
- Non-server script detection: Build-only tools (tsup, tsc, esbuild, etc.) are auto-detected and run without a proxy route. Use
proxy: falsein config for explicit control - Monochrome CLI output: Bold for headers and errors, dim for warnings and muted text, no color codes
0.10.3
Bug Fixes
- Stale TLD persisting across proxy restart: Fix the proxy reverting to a stale TLD (e.g.
.local) after restart because transient state markers were not cleaned up on stop
0.10.2
New Features
- Auto-inject
NODE_EXTRA_CA_CERTS: Child processes spawned byportless runnow automatically receiveNODE_EXTRA_CA_CERTSpointing to the portless CA certificate, so Node.js subprocesses trust the local CA without manual configuration
Bug Fixes
- Proxy startup on slow macOS
securitycommand: Fix the proxy failing to start when the macOSsecuritycommand takes longer than expected to verify CA trust - Lock contention with parallel commands: Fix lock contention that could cause failures when multiple
portlesscommands run simultaneously ERR_HTTP2_PROTOCOL_ERRORduring HMR: Fix HTTP/2 stream reset flood during hot module replacement causing protocol errors- Proxy auto-start in non-interactive terminals: Fix auto-start failing in non-interactive terminals (e.g. IDE task runners) and when previous proxy config exists
0.10.1
New Features
portless clean: New command stops the proxy if it is running, removes the local CA from the OS trust store when it was installed by portless, deletes allowlisted files under known state directories, and removes the portless-managed block from the hosts file. Custom--certand--keypaths are never removed
Improvements
- Hosts file sync by default: The proxy now keeps the hosts file in sync with active routes automatically (improves Safari and other setups where
.localhostsubdomains do not resolve to loopback). SetPORTLESS_SYNC_HOSTS=0to opt out. The managed block is removed from the hosts file when the proxy exits
0.10.0
New Features
- LAN mode: New
--lanflag exposes portless services to phones and other devices on the same network via mDNS.localhostnames. Auto-detects the active LAN IP, follows network changes, and supports--ip/PORTLESS_LAN_IPoverrides for VPN or multi-interface setups. Publishes mDNS records with platform-native tools (dns-sdon macOS,avahi-publish-addresson Linux). Adds*.localto generated certificate SANs so HTTPS works for LAN hostnames - VitePlus support: Auto-inject
--portfor VitePlus (vp) dev server
0.9.6
Bug Fixes
- WebSocket proxy memory leak: Add socket close/end handlers to prevent memory leaks in the WebSocket proxy
0.9.5
Bug Fixes
--forcekills existing process:--forcenow terminates the process that owns the conflicting route before registering a new one, instead of only removing the stale route entry- CA certificate included in TLS chain: The proxy now sends the CA certificate as part of the TLS chain, fixing
UNABLE_TO_VERIFY_LEAF_SIGNATUREerrors in clients that do not have the portless CA in their trust store
0.9.4
Bug Fixes
- README missing from npm package: The published npm package now includes its README. Previously
.gitignoreexcluded the copied README during packing; an.npmignoreoverride fixes this
0.9.3
Breaking Changes
- Origin/Referer header rewriting removed: The proxy no longer rewrites
OriginandRefererheaders. The feature introduced in 0.9.2 caused issues with certain backend frameworks and has been removed
0.9.2
New Features
- Origin/Referer header rewriting: The proxy now rewrites
OriginandRefererheaders for portless-managed hostnames so backend CSRF protections accept proxied requests
Bug Fixes
- Browser-blocked ports excluded from auto-selection: Ports that browsers refuse to connect to (e.g. 6666, 6667) are now excluded from automatic port assignment
- State directory preserved during sudo elevation: Fix
portless trustlosing the state directory when elevating to sudo - Windows OpenSSL config detection: Auto-detect
openssl.cnflocation on Windows whenOPENSSLDIRpoints to a non-existent path
0.9.1
New Features
- Project dev dependency install: portless can now be installed as a project dev dependency (
npm install -D portless) in addition to the global install. Thenpx/dlxguard now only blocks one-off downloads, not locally installed packages
Bug Fixes
portless truston fresh install: Fixportless trustfailing on a fresh install when no CA certificate exists yet. The command now generates the CA and server certificates automatically before trusting
0.9.0
Breaking Changes
- HTTPS on port 443 is now the default: The proxy defaults to HTTPS on port 443 instead of HTTP on port 1355. Auto-elevates with sudo on macOS/Linux to bind privileged ports. Use
--no-tlsfor plain HTTP on port 80, or-p 1355for the previous unprivileged port PORTLESS_HTTPSenv var inverted: HTTPS is on by default; setPORTLESS_HTTPS=0to disable (replaces the oldPORTLESS_HTTPS=1opt-in)
New Features
- HTTP-to-HTTPS redirect: When the HTTPS proxy runs on port 443, a companion HTTP server on port 80 automatically redirects all requests to HTTPS
- Auto-sudo for proxy lifecycle:
portless proxy startauto-elevates with sudo when binding privileged ports.portless proxy stopdoes the same when the running proxy is owned by root - Clean URLs: URLs are now
https://myapp.localhostinstead ofhttp://myapp.localhost:1355. No port numbers to remember
0.8.0
Breaking Changes
- Strict subdomain routing is now the default: Subdomains no longer automatically match parent hostnames (e.g.
api.myapp.localhostno longer routes tomyapp.localhost). Use the--wildcardflag orPORTLESS_WILDCARD=1env var to restore the previous behavior
New Features
--wildcardflag: Opt in to wildcard subdomain routing where subdomains match registered parent hostnames. Configurable viaPORTLESS_WILDCARDenv var
Bug Fixes
- Cert generation with dots in
$HOME: Fix TLS certificate generation failing when the home directory path contains dots - DNS label limit for
--nameflag: Fix regression where long--namevalues could exceed the 63-character DNS label limit - Windows
DEP0190deprecation warning: Silence Node.js deprecation warning on Windows by replacingshell: truewith explicitcmd.exe /d /s /cspawning - Windows duplicate
PATHentries: DeduplicatePATHenvironment variables in child process spawn on Windows
Improvements
- Removed chalk dependency: Replaced chalk with lightweight ANSI color utilities to reduce install size
- Automated release process: Added CI workflow for automated npm publishing and GitHub releases
0.7.2
Bug Fixes
--portinjection for package runners: Fix--portinjection for commands run via package runners likenpx,pnpm dlx, etc. (#150)- TLS cert generation: Fix TLS cert generation for long hostnames and proxy startup races (#149)
- Proxy crash on ECONNRESET: Handle
ECONNRESETerrors on TLS wrapper sockets to prevent proxy crash (#127) - Windows
node not recognized: Resolvenode not recognizederror on Windows when runningportless run(#126)
Documentation
- Added Windows to docs requirements section (#122)
Improvements
- Added GitHub Action to automatically publish packages to npm on release (#130)
0.7.1
Documentation
- Updated docs site header (#118)
0.7.0
Features
- Windows support: Full cross-platform support for Windows. Uses
os.tmpdir()for state directory,netstatfor port detection,certutilfor CA trust, and platform-aware command spawning. Includes Windows CI
Bug Fixes
--namesanitization inportless run: Stop replacing dots with hyphens in--namevalues. Dots are valid and intentional in hostnames likelocal.metaview- Worktree prefix only for linked worktrees: Only prepend the branch name for linked worktrees, not the root worktree. Previously any non-main branch got a prefix when multiple worktrees existed
- Windows hosts file paths: Use platform-aware hosts file path and error messages (Administrator vs sudo)
0.6.0
Features
- Custom TLD: Use
--tldto set a custom TLD (e.g..test) instead of.localhost. Configurable viaPORTLESS_TLDenv var. Auto-syncs/etc/hostsfor custom TLDs when started with sudo. Warns about risky TLDs like.localand.dev. Recommended:.test(IANA-reserved, no collision risk) portless getcommand: Print the URL for a service, useful for wiring services together (e.g.BACKEND_URL=$(portless get backend)). Applies worktree prefix by default; use--no-worktreeto skip--nameflag forportless run: Override the inferred base name while preserving the worktree prefix (e.g.portless run --name myapp next devin a worktree producesfix-ui.myapp.localhost)
Bug Fixes
- HTTPS proxy trust and stop on macOS with sudo: Fix CA trust check and
proxy stopwhen the proxy was started with sudo on macOS - DNS label length for worktree hostnames: Truncate worktree-prefixed hostnames to respect the 63-character DNS label limit
0.5.2
Documentation
- Add git worktree documentation.
portless runautomatically detects linked worktrees and prefixes the URL with the branch name (e.g.fix-ui.myapp.localhost)
0.5.1
Bug Fixes
- npm README: Copy root
README.mdinto the package at publish time so it appears on npmjs.com - homepage: Point npm homepage to https://port1355.dev
0.5.0
Features
portless runsubcommand: Automatically infer the project name frompackage.json, git root, or directory name instead of specifying it manually. In git worktrees, the branch name is prepended as a subdomain prefix (e.g.fix-ui.myapp.localhost) so each worktree gets a unique URL with no config changesportless aliascommand: Register routes for services not spawned by portless (e.g. Docker containers with published ports)PORTLESS_URLenv var: Child processes receivePORTLESS_URLcontaining the public.localhostURL so apps can self-reference their own URL--app-portflag: Specify a fixed port for the app instead of automatic assignment, also configurable viaPORTLESS_APP_PORTenv var- Wildcard subdomain routing: Subdomains now match registered hostnames (e.g.
tenant.myapp.localhostroutes tomyapp.localhost). Exact matches take priority /etc/hostssync: Automatically sync.localhosthostnames to/etc/hostsfor environments where.localhostdoes not resolve to127.0.0.1- Multi-distro Linux CA trust:
portless trustnow supports Arch, Fedora/RHEL/CentOS, and openSUSE in addition to Debian/Ubuntu - Expo and React Native support: Auto-inject
--portand--hostflags forexpo startandreact-native start - Branded error and status pages: The proxy renders styled HTML pages for 404, 502, 508, and other status codes
Bug Fixes
- Stream errors: Handle proxy stream errors gracefully to prevent unhandled exceptions from crashing the proxy
0.4.2
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. - sudo state directory permissions: System state directory (
/tmp/portless) now uses world-writable + sticky-bit permissions so non-root processes can register routes after a sudo proxy start. State files created under sudo are chowned back to the real user. - duplicate route names:
addRoutenow checks for an existing live route and throws an error if the hostname is already registered by a running process. Use--forceto override. - TLS SHA-1 rejection: Force SHA-256 for all CA and server certificate generation. Detect and regenerate existing SHA-1 certificates automatically.
- per-hostname certs for
.localhostsubdomains: Issue a per-hostname certificate with an exact SAN for every.localhostsubdomain.*.localhostwildcard certs are invalid because.localhostis a reserved TLD per RFC 2606. - terminal left in raw mode: Reset
stdin.setRawMode(false)on process exit so the terminal is not left in raw mode after Ctrl+C.
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. --forceflag: Override a route registered by another process withportless <name> --force <cmd>.
0.4.1
- Fixed Vite support by auto-injecting
--portand--hostflags - Added e2e tests for 11 frameworks (Next.js, Vite, Nuxt, Astro, Angular, SvelteKit, Remix, Solid, React Router, Hono, Express)
- Improved docs site
- Added Turborepo for build orchestration
0.4.0
- HTTP/2 + TLS support with auto-generated certificates
sudo portless trustcommand for system CA trust--https,--cert,--key,--no-tlsflags for proxy start- HTTPS configuration via
portless.jsonandPORTLESS_HTTPSenv var
0.3.0
- Configuration file support (
portless.json) PORTLESS=0to bypass the proxy- Port range customization
0.2.2
- Bug fixes and stability improvements
0.2.1
- Fixed proxy routing issues
0.2.0
- Added
--portflag to the proxy command
0.1.0
- Initial release
- Reverse proxy on port 1355
- Named
.localhostURLs for dev servers portless listcommand- Subdomain support