portctl
Never google "kill process on port" again.
Universal port & process manager for developers.
lsof meets htop meets docker ps — one command to see everything.
Install •
Quick Start •
Commands •
Config •
Contributing
Demo

$ portctl scan
PORT PROTO PID PROCESS USER LOCAL_ADDR STATE UPTIME
22 tcp 0 [system] 0.0.0.0 LISTEN -
3000 tcp 14230 node mike 127.0.0.1 LISTEN 2h14m
5432 tcp 1122 postgres pg 127.0.0.1 LISTEN 3d12h
8080 tcp 28456 java mike 0.0.0.0 LISTEN 45m
Why portctl?
Every developer hits this multiple times a week:
Error: listen EADDRINUSE: address already in use :::3000
Then you open a new tab and type:
lsof -i :3000 | grep LISTEN # wait, what was the flag again?
kill -9 <pid> # hope that was the right one
portctl replaces that entire dance with:
portctl kill 3000 # done
But it does much more -- a live TUI dashboard, Docker integration, a background guard daemon, and beautiful output that actually helps you understand what's running on your machine.
Installation
Homebrew (macOS & Linux)
brew install Cyberwex/tap/portctl
Go install
go install github.com/Cyberwex/portctl@latest
Shell script
curl -sSfL https://raw.githubusercontent.com/Cyberwex/portctl/main/scripts/install.sh | sh
From source
git clone https://github.com/Cyberwex/portctl.git
cd portctl
make install
Quick Start
# See everything listening on your machine
portctl scan
# Kill whatever is hogging port 3000
portctl kill 3000
# Live dashboard -- like htop for ports
portctl watch
# Deep-dive into a single port
portctl info 3000
# Get alerts when ports conflict
portctl guard start
Commands
portctl scan
Scan all listening ports and show the processes behind them.
portctl scan # All listening ports
portctl scan --port 3000 # Check a specific port
portctl scan --range 8000-9000 # Check a range
portctl scan --docker # Include Docker containers
portctl scan --json # Machine-readable output
portctl scan --plain # Tab-separated for scripting
portctl scan --filter node # Filter by process name
portctl kill
Kill processes by port with safety checks.
portctl kill 3000 # Kill process on port 3000
portctl kill 3000 8080 4200 # Kill multiple ports at once
portctl kill --dry-run 3000 # Preview what would be killed
portctl kill --force 3000 # SIGKILL immediately (no grace period)
portctl kill --yes 3000 # Skip confirmation
Safety first: portctl always shows what will be killed and asks for confirmation (unless you pass --yes).
portctl watch
Interactive TUI dashboard with live updates.
portctl watch # Launch dashboard
portctl watch --interval 2s # Custom refresh rate
Keyboard shortcuts:
| Key |
Action |
/ |
Search / filter |
j/k or Up/Down |
Navigate |
Enter |
Show process details |
K |
Kill selected process |
s |
Cycle sort column |
r |
Force refresh |
? |
Toggle help |
q |
Quit |
portctl guard
Background daemon that watches for port conflicts.
portctl guard start # Start the daemon
portctl guard stop # Stop it
portctl guard status # Check if running
portctl guard logs # View recent logs
When a different process takes over a watched port, you get an instant desktop notification.
portctl info <port>
Deep-dive into everything about a specific port.
portctl info 3000
Shows: PID, full command line, process tree, RSS memory, open file descriptors, network connections, environment variables (sensitive values masked), Docker container details.
portctl version
portctl version # Full build info
portctl version --short # Just the version number
portctl version --json # JSON format
Global Flags
--json JSON output (for scripting)
--plain Plain tab-separated output (for piping)
--no-color Disable colored output
--quiet Minimal output
--verbose Debug logging
Configuration
Config file location: ~/.config/portctl/config.yaml
scan:
docker: true
interval: 1s
guard:
watch_ports: [3000, 8080, 5432, 6379]
notify: true
output:
color: true
format: table # table | json | plain
kill:
confirm: true
graceful_timeout: 5s
How It Works
Linux: Parses /proc/net/tcp and /proc/{pid} directly -- no shelling out, maximum speed. TCP and TCP6 are scanned in parallel.
macOS: Uses lsof with hardcoded flags (security: no user input interpolation). Process details via ps.
Docker: Connects to the Docker daemon via unix socket using stdlib net/http -- no heavy Docker SDK dependency.
Comparison
| Feature |
portctl |
lsof |
netstat |
fuser |
ss |
| Show all ports + processes |
Yes |
Partial |
Partial |
No |
Partial |
| Kill by port |
Yes |
No |
No |
Yes |
No |
| Docker integration |
Yes |
No |
No |
No |
No |
| Interactive TUI |
Yes |
No |
No |
No |
No |
| Port conflict alerts |
Yes |
No |
No |
No |
No |
| Cross-platform |
Yes |
Yes |
Yes |
Linux |
Linux |
| Beautiful output |
Yes |
No |
No |
No |
No |
Built With
Contributing
Contributions are welcome! Please read our Contributing Guide first.
git clone https://github.com/Cyberwex/portctl.git
cd portctl
make help # See all available commands
make test # Run tests
make lint # Run linter
make build # Build binary
License
MIT -- see LICENSE.