Monitor ports, discover local app daemons, proxy traffic, and kill processes โ from the macOS menu bar or a terminal UI on any platform. Detects SSH forwards, Kubernetes port-forwards, and Cloudflare tunnels.
PortPilot inspects listening ports and local app daemons on the machine. Compared to a plain lsof wrapper, it:
- Classifies processes as System, App, or Developer Tool
- Detects tunnels โ SSH forwards,
kubectl port-forward, Cloudflare tunnels - Discovers Unix sockets โ local daemons like databases, dev servers, custom services
- Proxies traffic โ native TCP proxy built on Apple's Network.framework
- Runs as a menu bar accessory on macOS (no Dock icon) with a terminal UI and CLI on every platform
A glass-panel dropdown anchored to the menu bar with a unified, theme-synced design:
- Header โ PortPilot branding with refresh, settings, and more actions
- Live stats โ Active ports, Sockets, and Connections counts with pulsing status dot
- Integrated search โ Filter by port number, PID, or process name (Cmd+F hint)
- Protocol filters โ All / TCP / UDP toggle chips
- Source filters โ Local / Database / OrbStack / Tunnels
- Top Activity โ Top ports ranked by CPU + memory usage with See All toggle
- List View โ Ports grouped by connection type (Local, Database, Kubernetes, Cloudflare, SSH)
- Tree View โ Ports grouped by process name with expandable sections showing individual ports
- Schedules โ Cronjobs (user + system) with schedule, command, next-run time
- Port rows โ Port number, protocol badge, process name, PID, memory/CPU badges, hover kill/copy actions
- More menu โ Refresh, Kill All (with confirmation), Settings, Quit
- Footer โ Open PortPilot App / Tree View toggle + Sponsor link with author credit
- No Dock icon โ pure menu bar accessory app
Open via menu bar โ "Open PortPilot"
- Port list with filter pills (TCP/UDP/Unix, Web/Database/Dev/System/Favorites)
- CPU usage โ inline CPU % badge per process, color-coded by load
- Configuration panel โ connection details, process class, PID, uptime, CPU, CWD, port mapping
- Quick Proxy โ start/stop TCP proxy for any port from the config panel
- Port flow visualization โ ASCII diagram showing traffic path
- Logs panel โ activity log with per-port filtering
- Favorites, history, custom programs, reserved ports
Fully customizable look and feel โ Settings uses the same Liquid card design as the dropdown:
- 6 color themes โ Classic, Graphite, Sunset, Oceanic, Noir, Retro โ each with a recommended font pairing
- Theme sync โ dropdown, settings panel, and main window all use the same theme-derived colors
- Custom fonts โ pick any system font for UI and monospaced text, or drop
.ttf/.otffiles into theFonts/folder - Font size โ adjustable from 9px to 18px, applied consistently across all views
- Settings panels โ Liquid glass card design with themed sections, accent-colored icons, and sponsor link
| Theme | Character | Recommended Fonts |
|---|---|---|
| Classic | Vibrant and balanced | System Default + System Monospaced |
| Graphite | Calm and professional | SF Pro + SF Mono |
| Sunset | Warm and expressive | Avenir Next + Menlo |
| Oceanic | Deep and focused | SF Pro Rounded + SF Mono |
| Noir | Sharp and minimal | Helvetica Neue + Fira Code |
| Retro | Warm and nostalgic | American Typewriter + Courier New |
Built on Apple's Network.framework (NWListener + NWConnection):
- Forward traffic between any local ports
- Bidirectional relay with byte counting
- Start/stop from the Configuration panel
- Active proxy indicator with "Stop All"
Uses proc_pidpath to resolve executable paths and classify by heuristic:
| Type | Examples | How detected |
|---|---|---|
| System | mDNSResponder, WindowServer, launchd | /System/, /usr/libexec/, known daemons |
| Developer | node, postgres, docker, nginx, redis | Homebrew paths, known dev tools |
| App | Electron apps, .app bundles | /Applications/, .app/ in path |
| Other | Unclassified | Fallback |
Suspicious connections are flagged by matching against ~/.portpilot/blocklist.txt:
# ~/.portpilot/blocklist.txt โ one domain, IP, or CIDR per line
upload.dev
52.45.119.88
192.168.1.0/24
2a06:98c1:310b
Supports:
- Exact domain/IP matching
- Domain suffix matching (
.evil.commatchescdn.evil.com) - IPv6 prefix matching
- CIDR ranges
- Blocklisted connections show ๐จ in CLI, TUI, and menu bar
A full-featured terminal interface โ works on macOS, Linux, and WSL. Zero dependencies.
portpilot-tuiโญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ PortPilot TUI Linux โ
โ Ports Sockets Connections Schedules โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PORT PROTO PID CPU% MEM USER COMMAND TYPE โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ 3000 TCP 12345 0.3 45M user node Web โ
โโธ 5432 TCP 789 1.2 120M postgres postgres DB โ
โ 8080 TCP 4567 5.1 300M user java Web โ
โ 6379 TCP 1122 0.1 8M redis redis DB โ
โ 9090 TCP 3344 0.0 15M user grafana Web โ
โ โโ โ
โ โโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โโ/jk Navigate โ Enter Kill โ / Search โ Tab Switch โ i Info โ q Quit โ
โ 5 process(es) on Linux โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Keybindings:
| Key | Action |
|---|---|
โโ / j k |
Navigate |
Enter |
Kill process (with confirmation) |
/ |
Search / clear filter |
Tab |
Switch between Ports, Sockets, Connections, Schedules tabs |
i |
View detailed process info + connections |
r |
Refresh |
q |
Quit |
Connections tab shows all established outbound connections grouped by process with blocklist ๐จ markers.
Schedules tab shows cronjobs (user + system) with next-run calculation.
Detail View โ press i on any port:
โญ Process Info โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ Port: 5432 โ
โ Protocol: TCP โ
โ PID: 789 โ
โ User: postgres โ
โ Command: postgres โ
โ CPU: 1.2% โ
โ Memory: 120M โ
โ Path: /usr/lib/postgresql/15/bin/postgres โ
โ Work Dir: /var/lib/postgresql/15/main โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โญ Connections (3) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ LOCAL ADDRESS REMOTE ADDRESS STATE โ
โ 127.0.0.1:5432 127.0.0.1:48210 ESTABLISHEDโ
โ 127.0.0.1:5432 127.0.0.1:48212 ESTABLISHEDโ
โ *:5432 *:* LISTEN โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Esc Back โ x Kill โ X Force Kill โ q Quit
portpilot list # All listening ports (with CPU%)
portpilot list --start 3000 --end 9999 # Port range
portpilot list --proto tcp --json # JSON output (includes cpuUsage)
portpilot kill 5173 --force # Kill by port
portpilot kill :8080 # Colon prefix syntax
portpilot pid 8080 # Get PID for port
portpilot pids 3000 3001 3002 # Multiple PIDs
portpilot connections # All established connections (grouped by process)
portpilot connections --suspect # Only processes with >50 connections
portpilot connections --kill 12345 # Kill process by PID
portpilot connections --json # JSON output
portpilot schedules # User + system cronjobs
portpilot schedules --json # JSON output
portpilot interactive # TUI mode
portpilot proxy --port 1080 --host user@server # SOCKS proxyCLI table output includes CPU%, memory, and project/source info:
PORT PROTO PID CPU% MEM USER COMMAND PATH/PROJECT
3000 TCP 21082 0.0 45M user node wooosh/client
5432 TCP 63341 9.4 120M user postgres postgresql/15/main
8080 TCP 4567 5.1 300M user java my-api/server
Connections output with blocklist detection:
REMOTE PROCESS PID USER STATE COUNT
52.45.119.88:443 node 12345 user ESTABLISHED 1847 ๐จ
54.210.12.45:443 chrome 999 user ESTABLISHED 23
...
Schedules output:
SCHEDULE NEXT RUN USER COMMAND SOURCE
@hourly 04-03 14:00 user /usr/bin/some-script.sh user
*/5 * * * * 04-03 13:35 root /usr/bin/monitoring.sh /etc/cron.d/sys
brew install --cask sriinnu/tap/portpilotInstalls PortPilot.app to /Applications. Cask source: sriinnu/homebrew-tap. This installs only the menu bar app โ for the CLI/TUI, build from source below.
Manual install from the Releases page:
- Download
PortPilot-macOS-app.zip - Unzip it
- Move
PortPilot.appto/Applications
The release currently attaches:
PortPilot-macOS-app.zipportpilot-macos-cliSHA256SUMS.txt
git clone https://github.com/sriinnu/portpilot.git
cd portpilot
npm run releaseThis builds everything and installs:
PortPilot.appโ/Applications/(menu bar app)portpilotCLI โ/usr/local/bin/portpilot-tuiโ/usr/local/bin/(terminal UI)
portpilot list # CLI: list all listening ports
portpilot-tui # TUI: full interactive terminal UI1. Install Swift (if not already installed):
curl -L https://swiftlang.github.io/swiftly/swiftly-install.sh | bash
source ~/.profile # or restart your shell
swiftly install latest
swift --version # verify: should show Swift 6.xSee the official Swiftly Getting Started guide for details.
2. Build & install:
git clone https://github.com/sriinnu/portpilot.git
cd portpilot
npm run setup:linux # builds CLI + TUI and installs to /usr/local/binOr step by step:
npm run build:all:linux
sudo cp .build/release/portpilot /usr/local/bin/
sudo cp .build/release/portpilot-tui /usr/local/bin/3. Use it:
portpilot list # all listening ports with project paths
portpilot tui # launch rich terminal UI
portpilot-tui # direct launch
portpilot kill 8080 # kill by portRequires Swift for Windows:
git clone https://github.com/sriinnu/portpilot.git
cd portpilot
swift build -c release --product portpilot
copy .build\release\portpilot.exe "C:\Program Files\PortPilot\"Uses netstat + tasklist automatically:
portpilot list # all listening ports
portpilot kill 5000 --force # force kill
portpilot list --json # pipe to toolsNote: The TUI (
portpilot-tui) requires a POSIX terminal and works on macOS, Linux, and WSL. On Windows, use WSL or the CLI directly.
No config, no setup, no runtime dependencies. Platform detection is automatic โ same interface everywhere.
# macOS
npm run build # Build macOS app (xcodebuild)
npm run release # Build all + install app/CLI/TUI
# Linux / WSL
npm run setup:linux # One-command: build + install CLI + TUI
npm run build:all:linux # Build CLI + TUI only
# Common
npm run build:cli # Build CLI
npm run build:tui # Build TUI
npm run install:cli # Install CLI to /usr/local/bin
npm run install:tui # Install TUI to /usr/local/bin
npm run uninstall # Remove everything
npm run clean # Remove build artifacts| Platform | GUI App | TUI | CLI | Port Discovery | Install |
|---|---|---|---|---|---|
| macOS 13+ | Menu bar + window | portpilot-tui |
portpilot |
lsof + proc_pidpath |
npm run release |
| Linux | - | portpilot-tui |
portpilot |
ss |
npm run build:all:linux |
| WSL | - | portpilot-tui |
portpilot |
ss |
npm run build:all:linux |
| Windows | - | via WSL | portpilot |
netstat + tasklist |
swift build -c release |
| Shortcut | Action |
|---|---|
Cmd+R |
Refresh ports |
Cmd+F |
Search |
Cmd+, |
Settings |
Four Swift targets: PortPilot (macOS menu bar app), TerminalTUI (zero-dependency TUI engine), PortPilotTUI (the TUI app built on it), and PortManagerLib (shared port/socket/connection/cronjob discovery used by app, TUI, and CLI). Full source tree and tech stack: ARCHITECTURE.md.
TerminalTUI is a standalone, zero-dependency Swift library. Add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/sriinnu/portpilot.git", from: "3.0.0"),
],
targets: [
.executableTarget(
name: "MyApp",
dependencies: [.product(name: "TerminalTUI", package: "portpilot")]
),
]import TerminalTUI
struct MyScreen: TUIScreen {
mutating func render(into screen: inout Screen) {
screen.put(row: 0, col: 0, text: "Hello, TUI!", style: ANSI.bold + ANSI.fg(.cyan))
}
mutating func handleKey(_ key: KeyEvent) -> ScreenAction {
key == .char("q") ? .quit : .continue
}
}
let app = TUIApp(screen: MyScreen())
app.run()MIT โ see LICENSE for details.
ยฉ Srinivas Pendela 2024โ2026. All rights reserved.