Portless

Run your development environment, not your ports.

Portless starts processes, containers, databases, and frontends together, assigns safe ports behind the scenes, and gives every service a stable .localhost URL your team can remember.

Zero collisions Readable URLs Docker + processes
portless up
$ portless up

Workspace: sensx

✓ postgres   running   localhost:49231
✓ redis      running   localhost:49232
✓ api        running   api.sensx.localhost
✓ web        running   web.sensx.localhost

Done.

The local dev tax

Your local stack should not feel like an incident.

!

Port collisions

Another project, stale server, or container grabs the port first. Now startup depends on local cleanup rituals.

?

Localhost roulette

APIs, frontends, and admin tools drift across random numbers that nobody wants in screenshots or docs.

#

Setup folklore

Every repo grows its own startup lore: which command first, which port changed, which terminal tab matters.

Before and after

Replace port soup with named services.

Ports stay flexible internally. Developers open the same clean URLs every time.

Before
  • localhost:8080
  • localhost:8081
  • localhost:3000
  • localhost:5432
  • localhost:6379
After
  • api.sensx.localhost
  • billing.sensx.localhost
  • web.sensx.localhost
  • postgres assigned automatically
  • redis assigned automatically

How it works

Scan. Start. Open the right URL.

1

portless project scan

Find apps, Docker Compose services, frameworks, commands, and likely ports in the repo.

2

portless up

Start dependencies in order, allocate open ports, and wire routing for browser-facing services.

3

Open stable URLs

Use names like api.sensx.localhost while Portless handles the moving pieces.

Built for real workspaces

The boring parts of local dev, automated.

Collision-free ports

Keep app defaults. Portless finds safe loopback ports at runtime.

Memorable hostnames

Use stable .localhost names instead of sharing port trivia.

Processes + Docker

Run shell commands, containers, databases, and frontends together.

Dependency-aware startup

Bring up backing services before the apps that depend on them.

Caddy routing

Route local HTTP traffic through a proven proxy instead of custom glue.

Workspace isolation

Run similar repos side by side without fighting over 3000 or 8080.

Config generation

Scan a repo and get a useful portless.yaml starting point.

Named logs

Inspect service output by name instead of hunting terminal tabs.

Configuration

One file for the whole local stack.

Commands, dependencies, routes, and expected ports live with the repo instead of in stale onboarding notes.

portless.yaml
workspace:
  name: sensx

services:
  postgres:
    type: docker
    image: postgres:17
    internalPort: 5432

  api:
    type: process
    command: ./gradlew :api:bootRun
    port: 8080
    portEnv: SERVER_PORT
    dependsOn:
      - postgres
    route:
      host: api

  web:
    type: process
    workingDir: web
    command: npm run dev
    port: 5173
    route:
      host: web

Project isolation

Run two repos with the same defaults.

Project A
  • api expects 8080
  • postgres expects 5432
  • api.project-a.localhost
Project B
  • api expects 8080
  • postgres expects 5432
  • api.project-b.localhost

Scan first

Turn a repo into a runnable workspace.

Portless reads common framework, Compose, and Dev Container signals, resolves overlaps, and writes a starter config when you are ready.

portless project scan
$ portless project scan

Discovered:

✓ api       Gradle Spring Boot     high
✓ web       Vite                   high
✓ postgres  Docker Compose         high
✓ redis     Docker Compose         high

Run "portless project scan --explain" to see why each service was selected
Run "portless project scan --write" to generate portless.yaml

Install

Install once. Make every repo calmer.

Generate a config, start the stack, open services by name, and shut it all down cleanly.

Quick start
brew install portless-run/tap/portless

portless project scan --write
portless up
portless ps
portless logs api
portless open web
portless down