Portless: Nie wieder Port-Nummern merken
Statt localhost:3000, :8080, :5173 – mit portless bekommt jeder Dev-Server einen stabilen Namen. Ein CLI-Tool von Vercel, das Localhost aufräumt.
Jeder Entwickler kennt das: Du startest drei Projekte nebeneinander, und
plötzlich merkst du nicht mehr, ob die API auf :3001 oder :8080 lief. Oder
zwei Projekte wollen denselben Port, und alles bricht mit EADDRINUSE ab.
Cookies auf localhost überschneiden sich, Browser-Verlauf wird zu einem Chaos.
Was ist Portless?
Portless ist ein CLI-Tool (von Vercel, aktuell v0.13, pre-1.0), das Port-Nummern
durch benannte .localhost-URLs ersetzt. Statt http://localhost:3000 heißt
dein Dev-Server dann einfach https://myapp.localhost – mit echtem HTTPS und
HTTP/2.
- "dev": "next dev" # http://localhost:3000
+ "dev": "portless myapp next dev" # https://myapp.localhost
Das ist kein Proxy-Manager im Stil von Traefik oder nginx. Portless ist explizit für den lokalen Entwicklungs-Workflow gebaut – schnell eingerichtet, kein Docker, kein Config-Overhead.
Installation und erster Start
Global installieren (empfohlen):
npm install -g portless
Oder als Projektabhängigkeit:
npm install -D portless
Dann reicht ein einfaches portless im Projektverzeichnis. Das Tool liest
automatisch den "dev"-Script aus der package.json, leitet den App-Namen vom
Package-Namen, Git-Root oder Verzeichnisnamen ab und startet den Proxy:
portless
# -> Liest "dev" aus package.json, startet https://<project>.localhost
HTTPS mit HTTP/2 ist standardmäßig aktiviert. Beim ersten Run generiert Portless
eine lokale CA, vertraut sie und bindet Port 443. Mit --no-tls schaltest du
auf plain HTTP um.
Warum das besser ist als Port-Nummern
Portless nennt sieben konkrete Schmerzpunkte, die jeder kennt, der mit mehreren Dev-Servern arbeitet:
- Port-Konflikte: Zwei Projekte auf demselben Port? Mit Portless bekommt
jede App automatisch einen eigenen Port hinter ihrem Namen. Kein
EADDRINUSEmehr. - Port-Merk-Aufwand: War die API auf 3001 oder 8080? Mit Portless ist sie
immer
https://api.localhost. - Falsche App nach Refresh: Einen Server gestoppt, einen anderen auf demselben Port gestartet – und der Browser-Tab zeigt plötzlich etwas Komplett anderes. Benannte URLs eliminieren das.
- Cookie- und Storage-Kollisionen: Cookies auf
localhostgelten für alle Ports.localStoragegeht verloren, wenn sich Ports ändern. Jede.localhost-Subdomain bekommt ihren eigenen Scope. - Hardcodierte Ports in Config: CORS-Allowlists, OAuth-Redirect-URIs,
.env-Dateien – alles bricht, wenn sich Ports ändern. Mit Portless sind URLs stabil. - Browser-Verwirrung: Dein Verlauf für
localhost:3000ist ein Mix aus fünf Projekten. Benannte URLs trennen das sauber. - KI-Agenten am falschen Port: AI-Coding-Agenten erraten oder hardcodieren
Ports – besonders in Monorepos ein Problem. Eine stabile URL wie
https://myapp.localhostist deterministisch und zuverlässig.
Subdomains für Microservices
Das ist der Punkt, wo Portless für mich richtig interessant wird. In einem Setup mit Frontend, API und Docs reicht:
portless api.myapp pnpm start # -> https://api.myapp.localhost
portless docs.myapp next dev # -> https://docs.myapp.localhost
Jeder Service bekommt seinen eigenen Namen, seinen eigenen Scope, seine eigenen Cookies. Ohne Config-Datei, ohne Port-Mapping.
Git Worktrees ohne Kollisionen
Wer mit Git-Worktrees arbeitet, kennt das Problem: Zwei Branches desselben Projekts können nicht denselben Port nutzen. Portless erkennt Worktrees automatisch und prepended den Branch-Namen als Subdomain:
# Main-Worktree
portless run next dev # -> https://myapp.localhost
# Linked Worktree auf Branch "fix-ui"
portless run next dev # -> https://fix-ui.myapp.localhost
Keine Kollisionen, kein --force. Einmal in package.json eintragen, überall
funktionsfähig.
Monorepo-Support
Portless erkennt Monorepo-Strukturen (pnpm, npm, yarn, bun) und startet
automatisch alle Workspace-Packages mit einem "dev"-Script:
portless # im Monorepo-Root: startet alle Apps
Jedes Package bekommt eine Subdomain nach dem Muster
<package>.<project>.localhost. Wenn Turborepo erkannt wird, delegiert Portless
an turbo run und behält die Dependency-Orchestrierung bei. Eine
portless.json im Root erlaubt Overrides pro App:
{
"apps": {
"apps/web": { "name": "myapp" },
"apps/api": { "name": "api.myapp" }
}
}
Docker-Services einbinden
Mit portless alias registrierst du Services, die nicht von Portless verwaltet
werden – zum Beispiel einen Docker-Container:
portless alias my-postgres 5432 # -> https://my-postgres.localhost
portless alias redis 6379 # -> https://redis.localhost
Aliase überleben den Stale-Route-Cleanup und bleiben persistent.
Weiteres: Tailscale, Custom TLD, OS-Service
- Tailscale-Sharing: Mit
--tailscaleteilt man jede App im Tailscale-Netzwerk. Mit--funnelsogar öffentlich im Internet. - Custom TLD: Wer
.teststatt.localhostbevorzugt:portless proxy start --tld test. Empfohlen:.test(IANA-reserved). Vermeiden:.local(mDNS-Konflikt) und.dev(Google-owned, HSTS). - OS-Startup-Service:
portless service installrichtet einen Systemd/Launchd/Task-Scheduler-Dienst ein, der den Proxy nach Reboot automatisch startet.
Wie es funktioniert
Portless betreibt einen HTTPS-Reverse-Proxy auf Port 443. Jede App registriert
eine Route, die ihren Hostnamen auf einen zugewiesenen Port mappt. Requests an
https://<name>.localhost werden an die App weitergeleitet.
Der Proxy startet automatisch. Ein zufälliger Port (4000-4999) wird über die
PORT-Umgebungsvariable zugewiesen. Die meisten Frameworks (Next.js, Express,
Nuxt) respektieren diese automatisch. Bei Frameworks, die PORT ignorieren
(Vite, Astro, React Router, Angular), injiziert Portless automatisch den
passenden --port- und --host-Flag.
Für wen lohnt sich das?
Portless ist nicht für das kleine Nebenprojekt mit einem Dev-Server gedacht. Aber sobald:
- du regelmäßig mehrere Services gleichzeitig entwickelst,
- du in einem Monorepo arbeitest,
- du Git-Worktrees nutzt,
- oder KI-Agenten deine Dev-Server ansprechen sollen –
dann lohnt sich der Umstieg sofort. Die Installation dauert eine Minute, der Workflow-Gewinn ist spürbar.
Meine Einschätzung
Portless löst ein echtes Problem, das jeder Entwickler mit mehr als einem lokalen Service kennt. Das Tool ist noch pre-1.0 – die API kann sich ändern, und bei projektlokaler Installation können Versionsskew-Probleme zwischen Teammitgliedern entstehen. Aber der Ansatz ist überzeugend: Weg von Port-Nummern, hin zu benannten URLs.
Besonders die Kombination aus Git-Worktree-Support, Monorepo-Orchestrierung und Docker-Aliasen macht Portless zu einem Werkzeug, das den lokalen Entwicklungsalltag nachhaltig vereinfacht. Und dass HTTPS mit HTTP/2 out-of-the-box funktioniert, ist kein Luxus, sondern eine Notwendigkeit für moderne Browser-APIs (Service Workers, COEP, etc.).
Ich werde Portless in meinem Setup testen – und berichten.