PortKill finds local TCP listeners and stops the process bound to a port. It targets the “what is using port 3000?” moment: scan active listeners and kill the process without hand-rolling lsof/netstat and kill/taskkill.
This repository ships two clients:
| Client | Location | Best for |
|---|---|---|
| Menu bar app (macOS) | Sources/ |
Always-available globe icon in the menu bar |
| PortKill (Raycast) | raycast/ |
Launcher-first workflow inside Raycast (macOS, Windows, Linux) |
Pick whichever fits how you work; you do not need both running at once.
- Lists local TCP listeners (platform-specific tooling in the Raycast extension;
lsofon the menu bar app) - Shows port, process name, PID, and endpoint details
- Kills a single process from the list
- Kill All stops every unique PID (with confirmation)
- Sends
SIGTERMfirst, waits briefly, thenSIGKILLif the process is still alive
- macOS 14 or newer
- For the menu bar app: Swift 5.9+ and Xcode Command Line Tools
- For the Raycast extension: Raycast and Node.js 18+
killportapp/
├── Sources/KillPort/ # Swift menu bar app
├── raycast/ # Raycast extension (TypeScript)
├── script/ # Menu bar build & run helpers
├── Package.swift # SwiftPM manifest
└── dist/ # Generated KillPort.app (gitignored)
A menu-bar-only utility (no Dock icon). Look for the globe icon after launch.
From the repo root:
./script/build_and_run.shThis builds with SwiftPM, creates dist/KillPort.app, and opens it. The bundle is gitignored and safe to delete.
Other modes:
./script/build_and_run.sh --verify # build, launch, confirm process is running
./script/build_and_run.sh --debug # run binary under lldb
./script/build_and_run.sh --logs # launch and stream unified logsBuild only with SwiftPM:
swift build
swift build -c release- Refresh (
⌘R) — rescan listening TCP ports - Hover a row and click the red × — stop that process
- Kill All (
⌘K) — confirm, then stop every listed unique PID - Right-click the menu bar icon — Quit
swift build
swift build -c release
./script/build_and_run.sh --verifyThere is no test target yet; swift test reports no tests.
A Raycast command that lists listeners in Raycast’s UI, with a detail panel for full endpoint info. Supports macOS, Windows, and Linux (see raycast/README.md for per-OS tooling).
See also raycast/README.md for extension-specific notes.
Development (quickest to try):
cd raycast
npm install
npm run devLeave the terminal running, open Raycast, and run PortKill.
Import into Raycast (stays installed without npm run dev):
cd raycast
npm install
npm run buildIn Raycast: Manage Extensions → + → Import Extension → select the raycast/ folder (the one containing package.json).
Before publishing or running npm run lint, set "author" in raycast/package.json to your Raycast account username.
- Search filters by port, app name, or PID
- Refresh (
⌘R) — rescan - Kill All (
⌘K) — confirm, then stop every unique PID - Kill Process — on the selected row
- Open the detail pane for full endpoint / connection metadata
cd raycast
npm install
npm run dev # hot reload
npm run build # production build
npm run lint # requires valid Raycast author in package.json
npm run fix-lintPortKill can force-quit any process it lists. That is useful for stuck dev servers, but destructive if you kill the wrong thing. Only stop processes you recognize.
- Menu bar app:
script/build_and_run.shproduces an unsigned, ad-hoc signed app bundle for local use. There is no notarized installer yet. - Raycast extension: import the
raycast/folder locally, or runnpm run publishinraycast/to open a Store pull request (see Raycast publishing docs).