Portless

Run your development environment, not your ports.

Start processes, containers, databases, and web apps with one command. Portless automatically avoids collisions and exposes services through stable local URLs.

Safe ports Stable URLs One command
portless up
$ portless up

Portless 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

Every project wants the same ports.

!

Port collisions

Services fail because another project, stale process, or container is already bound to the port your app expects.

?

URL guessing

Developers bounce between localhost numbers instead of opening stable names that map to the service they need.

#

README archaeology

Setup docs drift as projects add services, change commands, and rely on tribal knowledge to get everything running.

Before and after

Replace localhost bookkeeping with service names.

Portless keeps ports flexible internally while your browser and team docs use stable local hostnames.

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

How it works

One flow from discovery to running URLs.

1

portless scan

Detect apps, Docker Compose services, common frameworks, and likely ports in the workspace.

2

portless up

Start services in dependency order, assign open ports, and wire local routing for web endpoints.

3

Open stable URLs

Use service hostnames like api.sensx.localhost while Portless handles the port details.

Built for real workspaces

Everything your local stack needs to start cleanly.

Automatic port assignment

Avoid collisions without rewriting project defaults.

Stable local hostnames

Open predictable URLs for every routed service.

Process + Docker orchestration

Run local commands and containers together.

Dependency ordering

Bring up databases before APIs and APIs before frontends.

Caddy-powered routing

Use a proven local proxy for clean service routes.

Project isolation

Run conflicting projects side by side with separate hostnames.

Config generation

Scan a workspace and write a useful starting config.

Developer-friendly logs

Inspect service output by name when something needs attention.

Configuration

Describe the stack once. Run it anywhere.

Portless config keeps service commands, dependencies, ports, and routes close to the project instead of scattered across shell notes and README updates.

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 conflicting projects side by side.

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

Scan first

Get from messy workspace to generated config.

Portless can inspect common project signals, rank confidence, and create a starter config with one write flag.

portless scan
$ portless scan

Discovered:

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

Run "portless scan --write" to create portless.yaml

Install

Install once. Use everywhere.

Start with Homebrew, generate a config, and run the local stack through stable service names.

Quick start
brew install portless-run/tap/portless

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