# portbar

> portbar is a free, open-source (MIT) native macOS menu bar app that shows every dev server running on your Mac, grouped by repository, git worktree, and branch. It flags servers that need attention (Detached, Forgotten, High CPU, Not responding) and stops a whole process tree in one click.

`lsof -i :3000` gives you a PID. portbar gives you the project, the worktree, and the branch, and it tells you which server you forgot.

## Install

- Homebrew: `brew install 1fc0nfig/tap/portbar`
- DMG: https://github.com/1fc0nfig/portbar/releases
- Requires macOS 14 Sonoma or later. Universal build (Apple silicon and Intel). Native Swift and SwiftUI, not Electron.

## Links

- [Website](https://portbar.app): product page
- [Source code](https://github.com/1fc0nfig/portbar): Swift, MIT license
- [Releases](https://github.com/1fc0nfig/portbar/releases): DMG downloads and changelog

## What it does

- Lists every process of the current user that listens on a TCP port, plus known tools without a port (Convex, Vitest, tsc watchers).
- Folds a process tree into one row: `bun run dev` → `concurrently` → `next dev` shows as "Next.js :3000".
- Groups rows by repository. All linked git worktrees show under one project, each with its branch.
- Shows the port, command, CPU sparkline, memory, and uptime for each service. Click a port to open it in the browser.
- Recognizes more than 45 frameworks, runtimes, and databases: Next.js, Vite, Astro, Nuxt, SvelteKit, Remix, Expo, Storybook, Wrangler, Convex, Supabase, Django, FastAPI, Flask, Rails, Laravel, Phoenix, Go, Rust, PostgreSQL, Redis, MongoDB, MySQL, Docker Desktop, OrbStack, Ollama, and more.
- Runs `package.json` scripts and custom commands from the menu bar, with full color logs.
- Stop sends SIGTERM to the whole process tree, children first, then SIGKILL after 3 seconds. No orphan workers.
- Shows pinned projects as a 2x2 dot grid in the menu bar.

## Status flags

- Detached: the terminal or tool that started the process is gone.
- Forgotten: detached and running longer than a set time (default 12 hours).
- High CPU: above 80% CPU for 3 scans in a row.
- Not responding: the port is open, but an HTTP check times out.

## Privacy

- Reads the process table through libproc and sysctl. It does not start lsof, ps, or git.
- No telemetry, no analytics, no crash reporting, no update check. The only network request is an HTTP health check to your own localhost.

## Limits

- macOS only. No Windows or Linux version.
- Ad-hoc signature, not notarized. The DMG needs right-click, Open on first launch. Homebrew removes the quarantine flag.
- No auto-update. Update with `brew upgrade` or a new DMG.
- Sees Docker Desktop and OrbStack, not the containers inside them. Local machine only.

## FAQ

### macOS says it cannot open portbar. Is something wrong?

No. portbar has an ad-hoc signature and is not notarized by Apple, so Gatekeeper stops the first launch of the DMG build. Right-click portbar in Applications, choose Open, and confirm. If macOS offers no Open button, go to System Settings, Privacy & Security, and click Open Anyway. You do this once. The Homebrew cask removes the quarantine flag, so a brew install opens normally.

### What does it need?

macOS 14 Sonoma or later, on Apple silicon or Intel. It is one universal build. No Windows or Linux version.

### Will it slow my Mac down?

It reads the process table through libproc, so a scan starts no other programs. It scans every 2 seconds while the panel is open (you can pick 1, 2, or 5) and every 5 seconds while it is closed. The HTTP check runs only while the panel is open, at most once a minute per port.

### Which servers does it show?

Every process of yours that listens on a TCP port, plus known tools that run without one, such as Convex, Vitest, or a tsc watcher. It names more than 45 frameworks, runtimes, and databases. It skips system processes and app bundles. It sees Docker Desktop and OrbStack, not the containers inside them.

### How does it find the repository and branch?

It walks up from the folder each process runs in and reads .git directly, without a git process. Linked worktrees show under the repository they belong to. A detached HEAD shows the short commit hash. Processes outside any repository go into a group called Other.

### Does it stop or kill anything on its own?

No. Flags only tell you. A server stops when you click Stop: portbar sends SIGTERM to the whole process tree, children first, and SIGKILL after 3 seconds to anything still alive. Force Kill sends SIGKILL at once. Scripts that portbar started stop when it quits, and a setting turns that off.

### Why not just use lsof or Activity Monitor?

If you need one PID for one port, lsof -i :3000 is fine. It does not tell you which project that PID belongs to, and Activity Monitor shows a dev server as a pile of node processes. portbar folds each tree into one named row, puts it under its repository and branch, and flags the one you forgot.

### Does anything leave my Mac?

No. The app has no telemetry, no analytics, no crash reporting, and no update check. Its only network request is the health check to your own localhost.

### How do I update it?

There is no auto-update. Run brew upgrade, or download the new DMG from GitHub Releases.

### What does it cost?

Nothing. portbar is MIT licensed. If it finds a server you forgot, star the repository.
