A fast, cross-platform port management tool. Kill, list, and watch processes on network ports.
portzap is a high-performance, cross-platform CLI for managing processes on network ports. It lets you kill, list, watch, and free ports without parsing platform-specific tools like lsof or netstat.
cargo install portzap
npm install -g portzap
git clone https://github.com/justinkarso/portzap cd portzap cargo install --path .
Requires Rust 1.74 or later. The npm package ships precompiled binaries; it does not need Rust installed.
Here are the most common portzap commands to get you started.
# Kill whatever is on port 3000 (with graceful SIGTERM → SIGKILL) portzap 3000 # See what's listening on port 5000 portzap list 5000 # List everything (all ports) portzap list # Watch port 8080 and auto-kill new processes portzap watch 8080 # Find the next available port after 3000 portzap free 3000
Kill processes on one or more ports. This is the default command when you run portzap with a port number.
portzap [OPTIONS] <PORTS>... portzap kill [OPTIONS] <PORTS>...
# Kill process on port 3000 portzap 3000 # Kill processes on multiple ports portzap 3000 8080 9090 # Kill processes on a port range portzap 3000-3010 # Interactive selection mode portzap -i 3000 # Dry-run (see what would happen) portzap --dry-run 3000 # Send SIGKILL immediately (no graceful shutdown) portzap --signal kill --no-graceful 3000
Display processes listening on all ports or on specific ports. Output can be in table, JSON, or plain text.
portzap list [OPTIONS] [PORTS]...
# List all listening ports portzap list # Show what's on port 3000 portzap list 3000 # List in JSON (structured output) portzap list --format json
Continuously monitor ports and automatically kill any process that binds to them. Ideal for keeping development ports free.
portzap watch [OPTIONS] <PORTS>...
# Watch port 3000 and kill any new process portzap watch 3000 # Watch multiple ports with 2-second poll interval portzap watch 3000 8080 --poll 2000 # Use immediate SIGKILL on new processes portzap watch --signal kill --no-graceful 3000
Find the next available (free) port starting from a given number. Useful for scripts that need to assign a port dynamically.
portzap free [OPTIONS] <PORT>
# Find the first free port ≥ 3000 portzap free 3000 # Search within a range portzap free 3000 --max 4000 # JSON output for scripting portzap free 3000 --format json
In JSON mode, a found port returns `{"port": 3000}`. If no free port is found, it returns `{"port": null, "error": "..."}`.
Block until a port reaches a certain state (free or occupied). Perfect for sequencing startup scripts.
portzap wait [OPTIONS] <PORT>
# Wait until port 3000 is free portzap wait 3000 # Wait until port 8000 becomes occupied (a server starts) portzap wait 8000 --until up # Wait with custom timeout and poll interval portzap wait 3000 --timeout 10 --poll 500 # Infinite wait (useful in CI) portzap wait 3000 --timeout 0
Generate shell completions for five popular shells. Pipe the output to the appropriate location for persistent setup.
# Bash portzap completions bash > ~/.local/share/bash-completion/completions/portzap # Zsh portzap completions zsh > ~/.zfunc/_portzap # Fish portzap completions fish > ~/.config/fish/completions/portzap.fish # PowerShell portzap completions powershell | Out-File -Encoding UTF8 $PROFILE # Elvish portzap completions elvish > ~/.config/elvish/completers/portzap
Launch an interactive terminal user interface (TUI) built with ratatui. It provides a real-time dashboard for browsing and killing processes on ports.
portzap gui
The TUI application reads its settings from `~/.config/portzap/config.toml`. The file is created automatically when you change a setting inside the GUI.
# ~/.config/portzap/config.toml # "dark" or "light" theme = "dark" # If true, kill happens immediately without confirmation dialog skip_confirm_dialog = false # Duration of the "zap" animation in milliseconds animation_duration_ms = 1000
You can toggle theme and confirmation dialog within the TUI using `t` and `c` respectively. Changes are saved immediately.
AI coding agents (Claude Code, Cursor, Copilot) often need to check ports and kill processes. portzap’s `--format json` produces structured output that is easy for agents to parse.
# Check what's on port 3000 portzap list 3000 --format json # List all ports portzap list --format json # Kill a process on port 3000 (result in JSON) portzap 3000 --format json # Preview what would be killed portzap --dry-run 3000 --format json # Find a free port portzap free 3000 --format json # Wait for a port to become free portzap wait 3000 --timeout 10 --format json
Add these lines to your project’s CLAUDE.md, .cursorrules, or similar to guide the agent:
When you need to check or kill processes on ports, use `portzap` instead of lsof/netstat: - Check a port: portzap list <port> --format json - Kill a port: portzap <port> --format json - List all ports: portzap list --format json - Find free port: portzap free <port> --format json - Wait for port: portzap wait <port> --timeout 10 --format json
portzap is built around a platform-agnostic scanner trait that abstracts away OS-specific APIs. The CLI dispatches to command modules, which use a factory to get the right scanner implementation.
CLI (clap) → Commands (kill/list/watch/free/wait/gui) ↓ PortScanner trait (scanner.rs) ↓ Platform implementations: - MacOS (libproc) - Linux (procfs) - Windows (stub)
Commands like `watch` and `wait` use `signal_hook` to handle SIGINT/SIGTERM gracefully, setting an `AtomicBool` that the main loop checks.
Uses `libproc` to iterate file descriptors of all processes and extract socket information. Full support.
Reads `/proc/net/tcp`, `/proc/net/udp` etc. and correlates inodes to process file descriptors via `procfs`. Full support.
The scanner and killer are stubs returning a “not yet implemented” error. Contributions to add Windows support (e.g., via `netstat` or WinAPI) are welcome.
portzap is published on both crates.io and npm. Cross-platform binaries are built via GitHub Actions on tags matching `v*`.
There are five npm packages under the `@portzap` scope:
Runs `cargo test`, `cargo clippy -- -D warnings`, and `cargo fmt --check` on both macOS and Ubuntu for every push and PR.
On a version tag, GitHub Actions builds binaries for all four platforms, packages them into npm platform packages, publishes to npm and crates.io, and creates a GitHub release with tarballs.