Changelog

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 --cert and --key paths 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 .localhost subdomains do not resolve to loopback). Set PORTLESS_SYNC_HOSTS=0 to opt out. The managed block is removed from the hosts file when the proxy exits

0.10.0

New Features

  • LAN mode: New --lan flag exposes portless services to phones and other devices on the same network via mDNS .local hostnames. Auto-detects the active LAN IP, follows network changes, and supports --ip / PORTLESS_LAN_IP overrides for VPN or multi-interface setups. Publishes mDNS records with platform-native tools (dns-sd on macOS, avahi-publish-address on Linux). Adds *.local to generated certificate SANs so HTTPS works for LAN hostnames
  • VitePlus support: Auto-inject --port for 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

  • --force kills existing process: --force now 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_SIGNATURE errors 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 .gitignore excluded the copied README during packing; an .npmignore override fixes this

0.9.3

Breaking Changes

  • Origin/Referer header rewriting removed: The proxy no longer rewrites Origin and Referer headers. 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 Origin and Referer headers 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 trust losing the state directory when elevating to sudo
  • Windows OpenSSL config detection: Auto-detect openssl.cnf location on Windows when OPENSSLDIR points 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. The npx/dlx guard now only blocks one-off downloads, not locally installed packages

Bug Fixes

  • portless trust on fresh install: Fix portless trust failing 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-tls for plain HTTP on port 80, or -p 1355 for the previous unprivileged port
  • PORTLESS_HTTPS env var inverted: HTTPS is on by default; set PORTLESS_HTTPS=0 to disable (replaces the old PORTLESS_HTTPS=1 opt-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 start auto-elevates with sudo when binding privileged ports. portless proxy stop does the same when the running proxy is owned by root
  • Clean URLs: URLs are now https://myapp.localhost instead of http://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.localhost no longer routes to myapp.localhost). Use the --wildcard flag or PORTLESS_WILDCARD=1 env var to restore the previous behavior

New Features

  • --wildcard flag: Opt in to wildcard subdomain routing where subdomains match registered parent hostnames. Configurable via PORTLESS_WILDCARD env 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 --name flag: Fix regression where long --name values could exceed the 63-character DNS label limit
  • Windows DEP0190 deprecation warning: Silence Node.js deprecation warning on Windows by replacing shell: true with explicit cmd.exe /d /s /c spawning
  • Windows duplicate PATH entries: Deduplicate PATH environment 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

  • --port injection for package runners: Fix --port injection for commands run via package runners like npx, pnpm dlx, etc. (#150)
  • TLS cert generation: Fix TLS cert generation for long hostnames and proxy startup races (#149)
  • Proxy crash on ECONNRESET: Handle ECONNRESET errors on TLS wrapper sockets to prevent proxy crash (#127)
  • Windows node not recognized: Resolve node not recognized error on Windows when running portless 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, netstat for port detection, certutil for CA trust, and platform-aware command spawning. Includes Windows CI

Bug Fixes

  • --name sanitization in portless run: Stop replacing dots with hyphens in --name values. Dots are valid and intentional in hostnames like local.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 --tld to set a custom TLD (e.g. .test) instead of .localhost. Configurable via PORTLESS_TLD env var. Auto-syncs /etc/hosts for custom TLDs when started with sudo. Warns about risky TLDs like .local and .dev. Recommended: .test (IANA-reserved, no collision risk)
  • portless get command: 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-worktree to skip
  • --name flag for portless run: Override the inferred base name while preserving the worktree prefix (e.g. portless run --name myapp next dev in a worktree produces fix-ui.myapp.localhost)

Bug Fixes

  • HTTPS proxy trust and stop on macOS with sudo: Fix CA trust check and proxy stop when 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 run automatically 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.md into the package at publish time so it appears on npmjs.com
  • homepage: Point npm homepage to https://port1355.dev

0.5.0

Features

  • portless run subcommand: Automatically infer the project name from package.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 changes
  • portless alias command: Register routes for services not spawned by portless (e.g. Docker containers with published ports)
  • PORTLESS_URL env var: Child processes receive PORTLESS_URL containing the public .localhost URL so apps can self-reference their own URL
  • --app-port flag: Specify a fixed port for the app instead of automatic assignment, also configurable via PORTLESS_APP_PORT env var
  • Wildcard subdomain routing: Subdomains now match registered hostnames (e.g. tenant.myapp.localhost routes to myapp.localhost). Exact matches take priority
  • /etc/hosts sync: Automatically sync .localhost hostnames to /etc/hosts for environments where .localhost does not resolve to 127.0.0.1
  • Multi-distro Linux CA trust: portless trust now supports Arch, Fedora/RHEL/CentOS, and openSUSE in addition to Debian/Ubuntu
  • Expo and React Native support: Auto-inject --port and --host flags for expo start and react-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 -c for command execution so shell scripts and version-manager shims (nvm, fnm, mise) are resolved correctly. Prepend node_modules/.bin to PATH so 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: addRoute now checks for an existing live route and throws an error if the hostname is already registered by a running process. Use --force to 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 .localhost subdomains: Issue a per-hostname certificate with an exact SAN for every .localhost subdomain. *.localhost wildcard certs are invalid because .localhost is 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 the X-Portless-Hops header. Respond with 508 Loop Detected and a message explaining the fix. Also detects loops on WebSocket upgrades.
  • --force flag: Override a route registered by another process with portless <name> --force <cmd>.

0.4.1

  • Fixed Vite support by auto-injecting --port and --host flags
  • 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 trust command for system CA trust
  • --https, --cert, --key, --no-tls flags for proxy start
  • HTTPS configuration via portless.json and PORTLESS_HTTPS env var

0.3.0

  • Configuration file support (portless.json)
  • PORTLESS=0 to 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 --port flag to the proxy command

0.1.0

  • Initial release
  • Reverse proxy on port 1355
  • Named .localhost URLs for dev servers
  • portless list command
  • Subdomain support