Overview
Portless automatically detects git worktrees and uses the branch name as a subdomain prefix. This gives each worktree its own URL without any configuration changes or name collisions.How Detection Works
Portless uses a multi-step heuristic to detect worktrees:Branch Name Handling
Default Branches
The main worktree (onmain or master) gets no prefix:
Slashes in Branch Names
Branches with slashes use only the last segment:Sanitization
Branch names are sanitized to be valid DNS labels:- Lowercased
- Non-alphanumeric characters replaced with hyphens
- Consecutive hyphens collapsed
- Leading/trailing hyphens trimmed
- Truncated to 63 characters (RFC 1035 limit)
Fallback Detection
If thegit binary is unavailable, portless falls back to parsing the .git file:
Examples
Basic Worktree Setup
Both instances run simultaneously without conflicts.Monorepo with Multiple Services
Explicit Subdomain with Worktree Prefix
If you use an explicit subdomain, the worktree prefix is still prepended:Disabling Worktree Detection
Use the--no-worktree flag with portless get to skip worktree detection:
There is currently no flag to disable worktree detection for
portless run or portless <name>. If you need this, use --name to force a specific name:Integration with package.json
Put portless run in your package.json scripts:
package.json
- Main worktree:
pnpm dev→http://myapp.localhost:1355 - Linked worktree:
pnpm dev→http://fix-ui.myapp.localhost:1355
Wildcard Subdomain Routing
Worktree URLs benefit from wildcard subdomain routing. If you registermyapp.localhost, then:
myapp.localhostroutes to your appfix-ui.myapp.localhostroutes to your appauth.myapp.localhostroutes to your appanything.myapp.localhostroutes to your app
Wildcard routing matches the longest registered suffix. If you explicitly register
fix-ui.myapp.localhost, that route takes precedence over the wildcard match for myapp.localhost.