Skip to content

Portless

★ New
assess
DevOps open-source MIT open-source

At a Glance

Open-source CLI by Vercel Labs that replaces ephemeral port numbers with stable named .localhost URLs by running a local HTTPS reverse proxy, reducing developer friction across multi-service and AI agent workflows.

Type
open-source
Pricing
open-source
License
MIT
Adoption fit
small, medium
Top alternatives

What It Does

Portless solves a common developer friction point: hardcoded port numbers in config files, cookie domains, CORS allow-lists, and OAuth redirect URIs. Instead of accessing your app at http://localhost:3000, you run portless myapp next dev and access it at https://myapp.localhost. A persistent daemon running on port 443 (or 1355 without TLS) routes incoming requests to whichever ephemeral port your dev server is currently occupying, routing by the Host header.

On first run, portless generates a local Certificate Authority, adds it to the OS trust store (macOS Keychain, NSS, Windows certutil), and injects NODE_EXTRA_CA_CERTS into child processes so Node.js trusts local HTTPS connections without warnings. The .localhost TLD resolves to 127.0.0.1 natively on macOS, Linux, and Windows without /etc/hosts modifications, making the setup near-zero-config for the base case.

Key Features

  • Named .localhost URLs: Maps myapp.localhost → dynamic port via Host-header routing; eliminates port bookkeeping across team members and restarts.
  • HTTPS + HTTP/2 by default: Automatic local CA generation, system trust store registration, and per-hostname certificate issuance on demand.
  • Framework auto-detection: Heuristically injects --port, --host, and related flags for Next.js, Vite, Nuxt, Astro, Angular, SvelteKit, Remix, Solid, React Router, Hono, Express (11 frameworks tested as of v0.4.1).
  • Environment variable injection: Exposes PORT, HOST, and PORTLESS_URL to child processes, letting frameworks and agents discover the assigned port without flag parsing.
  • Git worktree subdomain prefixing: In a linked worktree, the checked-out branch name becomes a subdomain prefix (e.g., feat.myapp.localhost), preventing port collisions across concurrent branches without configuration changes.
  • Subdomain organization: Supports nested services (api.myapp.localhost, docs.myapp.localhost) via CLI flags.
  • Custom TLDs: --tld flag accepts .test (IANA-reserved) or arbitrary strings; LAN mode (--lan) exposes services to the local network via mDNS as .local addresses.
  • Monorepo pnpm workspace + Turborepo: Internal project structure designed for contributor-friendly workspace management.
  • WebSocket proxying: Persistent WebSocket connections proxied correctly (memory-leak fix in v0.9.6).
  • Clean uninstall: portless clean removes daemon state, hosts file entries, and the local CA from the OS trust store.

Use Cases

  • Multi-service local development: Running a frontend, API, and auth service simultaneously without tracking which service claims which port; all accessible at predictable subdomains of a single project name.
  • Git worktree concurrent development: Teams (or AI coding agents) working multiple branches in parallel git worktrees where each branch auto-gets a unique subdomain, eliminating port conflicts.
  • AI agent dev server management: AI coding agents (Claude Code, Codex CLI, OpenHands) that spin up dev servers need stable, predictable URLs. Portless’s environment variable injection means agents can read PORTLESS_URL rather than parsing stdout for port numbers.
  • OAuth and cookie domain consistency: OAuth redirect URIs and cookie Domain attributes can be set to a stable hostname rather than localhost:PORT, reducing configuration drift between team members.
  • LAN testing across devices: --lan flag makes the dev server discoverable via mDNS across the local network, enabling mobile device testing without manual IP lookup.

Adoption Level Analysis

Small teams (<20 engineers): Fits well. Near-zero-config for single-machine use, free, and eliminates a genuine daily friction point. The main cost is understanding the local CA trust model and the background daemon lifecycle.

Medium orgs (20–200 engineers): Fits with caveats. The tool is pre-1.0 and from Vercel’s experimental arm (not the product team), introducing longevity risk before deep workflow integration. Teams on non-macOS/Linux (Alpine containers, Windows-primary) should evaluate carefully given documented Windows and container edge cases.

Enterprise (200+ engineers): Does not fit currently. The pre-1.0 status, absent SLA, Vercel Labs provenance (no backwards-compatibility guarantee), and local CA trust model make it unsuitable for regulated environments or teams with strict control over system trust stores.

Alternatives

AlternativeKey DifferencePrefer when…
mkcert + CaddyBattle-tested combination; Caddy handles the proxy, mkcert the CA; no auto-detection or worktree integrationYou want maximum control and stability over your local HTTPS stack
mkcert + nginxMaximum configurability for complex proxy rulesYou already run nginx locally or need advanced routing
ngrok / localtunnelCreates public tunnel, not a local proxyYou need to expose local services to external stakeholders or webhooks
Vercel CLI (vercel dev)First-party Vercel integration, tightly coupled to Vercel project structureYour stack is entirely Vercel-hosted and you want production parity

Evidence & Sources

Notes & Caveats

  • Vercel Labs provenance: Vercel Labs is an experimental incubator. Projects under this umbrella have been discontinued without notice in the past. Avoid deep coupling (CI scripts, onboarding docs, config-as-code) until the project reaches 1.0 or is promoted to a first-party Vercel package.
  • Pre-1.0 instability: The changelog from v0.9.x to v0.10.x includes breaking bug fixes to proxy startup, lock contention, and HTTP/2 behavior. API stability is not guaranteed.
  • Local CA trust model: Adding a CA to the system trust store is a meaningful security action. If ~/.portless/ is exfiltrated, the attacker can sign certs trusted by your machine for any hostname. This is the same risk as mkcert; it is an intrinsic local-HTTPS trade-off, not specific to portless.
  • Windows edge cases: Multiple GitHub issues document certificate handling and path problems on Windows (Issue #124: portless trust bug; Issue #15: Windows support questions). macOS and Linux are the primary tested platforms.
  • Branch-name subdomain sanitization: The git worktree subdomain-prefixing feature does not document how it handles branch names with slashes, uppercase letters, or other DNS-invalid characters (e.g., feature/JIRA-123). Edge cases may produce invalid subdomains silently.
  • Container environments: .localhost wildcard resolution relies on the OS resolver. Alpine Linux and other musl-based containers may not resolve *.localhost without explicit /etc/hosts entries, limiting usefulness in containerized dev environments.
  • Port 443 requires elevated privileges: On macOS/Linux, binding port 443 requires sudo. Portless handles this with sudo auto-elevation, but in environments with strict sudo policies this may fail silently or require additional configuration.

Related