A cross-platform TUI (Terminal User Interface) for monitoring network ports and managing processes. Built with Rust for performance and portability.
- π Real-time Port Monitoring - View all listening and established connections
- π₯οΈ Process Details - Inspect memory, CPU, command line, and environment variables
- β‘ Process Control - Gracefully terminate or force kill processes
- π Smart Filtering - Filter by port number, process name, protocol, or state
- π¨ Rich TUI - Clean interface with color-coded states and intuitive navigation
- π Cross-Platform - Works on Linux, macOS, and Windows
cargo install portwatchgit clone https://github.com/dedsecrattle/PortWatch
cd PortWatch
cargo install --path .git clone https://github.com/dedsecrattle/PortWatch
cd PortWatch
cargo build --release
./target/release/portwatch# Start PortWatch with default settings
portwatch
# Set custom refresh interval (in milliseconds)
portwatch --refresh-interval 5000
# Start with a filter applied
portwatch --filter 3000β- Move upβ- Move downEnter- View detailed process information
r- Refresh port list/- Start filter mode (type to filter)Esc- Clear filterk- Graceful stop (SIGTERM on Unix, graceful termination on Windows)K- Force kill (SIGKILL on Unix, force termination on Windows)
a- Toggle alerts panel (recent fired alerts)E- Open alert rules editor (add/edit/delete rules; saved to config)?- Toggle help screenq/Ctrl+C- Quit
Rules are stored as JSON. The canonical location is:
{config_dir}/portwatch/alerts.jsonwhereconfig_diris the platform config directory (e.g.~/.configon Linux,~/Library/Application Supporton macOS, Roaming AppData on Windows).
If an older file exists at ~/.config/portwatch/alerts.json, it is still loaded automatically; new saves always write to the canonical path above.
You can edit rules in the TUI with E (see on-screen hints) or edit the JSON file directly.
- Example config:
examples/alerts.example.jsonβ copy and adapt to your config path. - Field reference:
docs/alert-rules.mdβ rule object, severities, and everyconditionvariant with parameters.
Press / to enter filter mode, then type:
- Port number:
3000 - Process name:
node - Protocol:
tcporudp - State:
listen,established, etc.
Press Enter to apply or Esc to cancel.
- Uses
/procfilesystem for native port-to-PID mapping - Parses
/proc/net/tcp,/proc/net/udpfor connection data - Requires read access to
/proc(usually available to all users)
- Uses
lsof -ifor port scanning - Requires
lsofto be available (standard on macOS)
- Uses
netstat -anofor port scanning - Requires
netstatto be available (standard on Windows)
PortWatch uses a modular architecture with platform-specific backends:
src/
βββ main.rs # Entry point and event loop
βββ app.rs # Application state and reducer
βββ events.rs # Input handling and actions
βββ models.rs # Core data structures
βββ backends/ # Platform-specific implementations
β βββ mod.rs # Backend traits
β βββ linux.rs # Linux /proc implementation
β βββ macos.rs # macOS lsof implementation
β βββ windows.rs # Windows netstat implementation
βββ ui/ # TUI components
βββ mod.rs
βββ theme.rs
βββ layout.rs
βββ ports_table.rs
βββ details.rs
βββ footer.rs
- Rust 1.70 or later
- Platform-specific tools:
- Linux: Access to
/procfilesystem - macOS:
lsofcommand - Windows:
netstatcommand
- Linux: Access to
Some operations may require elevated permissions:
- Viewing ports: Usually works without special permissions
- Killing processes: May require root/admin for processes owned by other users
- Stack sampling on Linux (perf/eBPF)
- Process tree view
- Export to JSON/CSV
- Container awareness
- Language-specific detection (Node.js, Python, Java)
- Network activity sparklines
MIT OR Apache-2.0
Contributions are welcome! Please feel free to submit issues or pull requests.