Self-hosted service
productdevbook/port-killer avatar
productdevbook/port-killer

PortKiller: a menu bar and system tray app for finding and killing the process on a port

A powerful cross-platform port management tool for developers. Monitor ports, manage Kubernetes port forwards, integrate Cloudflare Tunnels, and kill processes with one click.

5,090 stars203 forksSwiftMIT

At a glance

What is it?
PortKiller is a Swift and SwiftUI desktop tool from productdevbook that lists listening TCP ports, kills the owning process, manages kubectl port-forward sessions and shows Cloudflare Tunnel status. It is a GUI convenience layer, not a replacement for lsof or netstat in scripts.
Who is it for?
Adopt PortKiller if you work on macOS 15 or Windows 10 and lose time hunting for the process holding a port, especially if you also keep kubectl port-forward sessions open all day. Do not adopt it for headless Linux servers, CI images or scripted cleanup, because it is a GUI app with no documented CLI, and do not treat it as a general process manager.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What PortKiller actually solves for a developer on macOS or Windows

The recurring failure is a port already in use. A dev server refuses to start, a Docker container cannot bind 5000, and the fix is to find which PID owns the port and terminate it. On macOS and Windows the built-in tools are not friendly for that: lsof -i and netstat -ano both print columns you have to read, and neither offers a kill button. PortKiller is a native desktop app that does the lookup and the termination in one window. The README describes it as a cross-platform port management tool for developers, with auto-discovery of all listening TCP ports, one-click process termination with both graceful and force kill, auto-refresh on a configurable interval, search and filter by port number or process name, favorites, watched ports with notifications, and smart categorization into Web Server, Database, Development and System. The audience is narrow and clear: developers on macOS 15.0+ or Windows 10+ who want a visual list rather than a shell pipeline. The README states no Linux build, so anyone on a Linux workstation is out of scope.

How the port discovery and kill path works

The repository is split into platforms/ and portkiller-core/, with the macOS app under platforms/macos and a shared core module alongside it. That layout implies the platform-specific UI code sits on top of a common layer that performs the port enumeration and process lookup, which is what makes a single Swift codebase serve both a macOS menu bar item and a Windows system tray app. The README does not name the underlying system call or command used to enumerate sockets, so the exact mechanism is not documented; what is documented is the user-visible behavior: the app discovers listening TCP ports automatically, refreshes them on an interval you configure, and offers graceful and force termination per process. The kill action is the interesting design choice. Graceful first, force second, mirrors SIGTERM then SIGKILL on Unix, and it matters because a dev server that flushes state on shutdown behaves differently from one that is killed outright. PortKiller does not attempt to explain what graceful means on Windows, and the README is silent on whether the two options map to different Windows APIs. Ports can be starred as favorites or watched, and watched ports raise notifications, which turns the app into a small monitoring surface rather than only a cleanup tool.

Installing PortKiller with Homebrew and killing your first stuck port

On macOS the README gives a Homebrew cask as the primary path. The cask lives in the project's own tap, so the fully qualified name includes the tap prefix:

bash
brew install --cask productdevbook/tap/portkiller

After that, PortKiller appears as a normal macOS application and the README says it integrates with the menu bar. The alternative is to download the .dmg from GitHub Releases and install it manually. On Windows there is no package manager step in the README: you download a .zip from GitHub Releases and extract it.

Once the app is running, the workflow is: open the port list, type a port number or a process name into the search field, select the row, and terminate. If you want the port to stay visible, star it as a favorite. If you want a notification when it changes state, mark it as watched. The README states that auto-refresh runs on a configurable interval, so a process that grabs the port after you closed the window will show up on the next refresh rather than immediately.

The second feature worth setting up early is kubectl port-forward management. The README describes creating and managing port-forward sessions from the app, with auto-reconnect on connection loss, connection logs, status monitoring and notifications on connect and disconnect. That means the app holds the kubectl process for you, so the forwarding session survives a dropped connection without you re-running the command by hand.

Where PortKiller is the wrong tool

The README documents no command line interface. There is no portkiller kill 5000 style invocation, no JSON output, no exit code to branch on. If your cleanup step lives in a Makefile, a shell script, a test fixture or a CI job, PortKiller cannot participate, and you should keep using lsof plus kill or a platform equivalent. The same applies to headless machines: the app targets macOS and Windows desktops, and the README lists no Linux build, so a remote server is out of reach. A second boundary is scope. PortKiller manages ports and kubectl port-forward sessions. It is not a general process manager, and the README makes no claim about memory, CPU or service supervision; reaching for it to restart a stuck daemon is a misuse. Third, the Cloudflare Tunnel feature is described as viewing and managing active tunnel connections and quick access to tunnel status. The README does not say it can create a tunnel, configure ingress rules or manage credentials, so if you need to define a new tunnel you still do that elsewhere. Finally, the app is a GUI with a refresh interval: there is a window between a port being taken and the list updating, and any workflow that needs to react within milliseconds is better served by a watcher process.

PortKiller against Raycast port commands and plain lsof

The closest everyday alternative for macOS users is a launcher extension that kills ports, and the related searches around Raycast port commands show that people compare the two. The difference in approach is where the action lives. A launcher extension is invoked from the keyboard, takes a query, and disappears; it has no persistent list, no favorites, no watched ports and no refresh interval, because it runs only when you call it. PortKiller keeps a live window or menu bar item that shows the current port table and re-reads it on a schedule. That is better when you want to see what is listening, and worse when you only want to kill one port and get back to the editor. The second alternative is the shell itself. lsof -i :5000 and netstat -ano give you the PID, and kill ends the process; nothing needs to be installed, it works over SSH, and it composes into scripts. PortKiller trades that composability for categorization, notifications and the kubectl port-forward management that no shell one-liner provides. If you already have a terminal open all day and never keep port forwards alive, the app adds a dependency without adding capability.

Release cadence, licence and what upgrading costs you

The last push to the repository was on 2026-07-24, and the most recent release listed is v3.3.3 from 2026-06-21, preceded by v3.3.2 on 2026-06-13 and v3.3.1 on 2026-02-16. The repository is not archived. Those dates describe a project that ships patches in clusters rather than on a fixed schedule, and the top-level appcast.xml suggests the macOS build has an update feed, though the README does not document an in-app updater or how it is triggered. On macOS, upgrading through the Homebrew cask is a brew upgrade away, which is the cheapest path. On Windows the README points at a .zip on GitHub Releases, so upgrading means downloading a new archive and extracting it again; the README does not describe an installer or an automatic update, and it does not document rollback to a previous version. Budget for checking releases manually on that platform. The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are included; the repository keeps the full text in LICENSE. That is a permissive arrangement, but it says nothing about the kubectl and cloudflared binaries the app drives, which carry their own licences, and nothing here is legal advice.

Editorial conclusion

Adopt PortKiller if you work on macOS 15 or Windows 10 and lose time hunting for the process holding a port, especially if you also keep kubectl port-forward sessions open all day. Do not adopt it for headless Linux servers, CI images or scripted cleanup, because it is a GUI app with no documented CLI, and do not treat it as a general process manager. Before relying on it, confirm the Homebrew cask installs on your macOS version, check whether your Cloudflare Tunnel runs as a named tunnel or as cloudflared in a terminal, and decide whether the GitHub Releases zip is an acceptable update path on Windows, since the README does not describe an in-app updater.

Frequently asked questions

How do I kill a process on a port with PortKiller?

Open the app, find the port in the auto-discovered list, and use the one-click termination action. The README states both graceful and force kill are available, so you can try the graceful path first and escalate if the process does not exit.

How do I kill port 5000 with PortKiller?

Search for 5000 in the app's search field, which the README says filters by port number or process name, then terminate the matching process from that row. There is no documented command line equivalent, so the kill happens through the interface.

Is there a PortKiller app for Mac?

Yes. The README lists macOS 15.0 or later and gives a Homebrew cask, brew install --cask productdevbook/tap/portkiller, as well as a .dmg download from GitHub Releases. It also describes menu bar integration on macOS.

Does PortKiller work on Windows?

The README lists Windows 10 or later and describes a system tray app with a native UI. Installation is a .zip downloaded from GitHub Releases and extracted, with no package manager command documented.

Can PortKiller manage kubectl port-forward sessions?

Yes. The README states you can create and manage kubectl port-forward sessions, with auto-reconnect on connection loss, connection logs, status monitoring and notifications when a session connects or disconnects.

What does PortKiller do with Cloudflare Tunnels?

The README describes viewing and managing active Cloudflare Tunnel connections and quick access to tunnel status. It does not document creating tunnels or editing ingress configuration, so those steps stay outside the app.

Official sources

  1. Issues
  2. License: MIT
  3. productdevbook/port-killer on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/productdevbook-port-killer.svg)](https://hysenlabs.com/projects/productdevbook-port-killer)