harbor/

your projects' dev servers,
one click away

harbor is a small native macOS app for the thing you do before you write any code: starting npm run dev in one folder, php artisan serve and a queue worker in another — and then remembering which of them is still running.

$ git clone https://github.com/erenbekman/harbor.git
$ cd harbor && ./install.sh
┌──────────────┬─────────────────────────────────────────────────┐      ┌───────────────┐
│ ● nott     2 │ nott                  start all   ✦ magic   +   │      │      ───      │
│ ● ustad      │ ~/Documents/GitHub/nott                         │      │ ● nott      2 │
│ ● medvise    │                                                 │      │   ■ backend   │
│ ● harbor     │  ■  backend                                   › │      │     ● :4000   │
│              │       ● running · :4000                         │      │   ▶ horizon   │
│ + add        │                                                 │      │     ○ stopped │
│              │  ■  client                                    › │      │ ● ustad       │
│              │       ● running · :3000                         │      │   ■ serve     │
│              │                                                 │      │     ● starting│
│              │  ▶  horizon                                   › │      └───────────────┘
│              │       ○ stopped                                 │       ↑ the edge strip,
│              │                                                 │         over every app
│ ‹ collapse   │  ▶  admin                                     › │
│              │       ✕ exited (1) · :3000 held by node (4821)  │
└──────────────┴─────────────────────────────────────────────────┘

The window is where you set things up. The strip on the right edge of the screen is where the rest of the day happens — it is there while you are in the editor, and pressing play never takes your focus.

01 what it does

tmux
Every service is a tmux session, so they outlive the app. Quit harbor and your dev server keeps serving; open it again and it is adopted, not started twice. An update never touches them.
measured ports
You never type a port into harbor. It walks the pane's process tree and asks lsof what is actually listening — so :3000 on a row means something really is on 3000, and the row offers to open it.
magic
For what pattern matching cannot see — a monorepo, a PM2 ecosystem.config.js, a socket server, a cron process — claude -p reads the project with Read, Glob and Grep, every other tool taken away, and answers with services and the file each came from. A checklist you approve; nothing is added on its own.
the edge strip
A column of project chips on the right edge of the screen, above every app and on every Space. Hover for the services, press play without losing focus in your editor, drag it where you want it.
crashes
A service that exits keeps its output and its exit code instead of vanishing. If the port was taken, the row names the process holding it and offers to kill it. Optionally it restarts itself, three times, then leaves it alone.
⌃⌘H
From anywhere: type a project or service name, Enter starts or stops it. No window, no mouse. The same list lives in the menu bar, and harbor updates itself from its own releases.

02 how it works

01

one tmux session per service

Named from a stable hash of the project path, so the same folder maps to the same session on every launch. That is how harbor finds services it did not start in this run instead of starting a second copy of your dev server.

02

one poll answers for everything

Every two seconds: one list-panes for liveness and exit codes, one ps for the process tree, one lsof for the ports. No per-service polling, and nothing is drawn again unless the value actually moved.

03

a port is not an answer

Give a service a health path and the dot turns green only when the URL responds — not when the port opens. While a framework is still booting, yellow is the truth.

# a service, really
tmux -S /tmp/harbor-501.sock new-session -d -s hb-3b92hjqj-5de35ab8 \
  'cd backend && npm run dev'

# what the dot means
● running   pane alive, health answering, :4000
● starting  pane alive, nothing listening yet
✕ exited    kept on screen with its exit code
○ stopped   not running

03 install

$ git clone https://github.com/erenbekman/harbor.git $ cd harbor $ ./install.sh

Builds a release bundle, installs it into /Applications and launches it. Installs tmux with Homebrew if you do not have it. The app is ad-hoc signed, so the first launch may need right-click → Open.

add a folderharbor reads it and offers what it finds — npm, pnpm, yarn, bun, artisan, django, docker compose.
or press magicclaude reads the project for everything else.
it updates itselfsettings → about checks the latest release and installs it; your services keep running through it.