Every developer has seen this at 2 AM:
Error: listen EADDRINUSE: address already in use :::5173
The usual workflow? Open a terminal, run netstat or lsof, copy the PID, run kill -9. Simple enough — until you grab the wrong PID and accidentally terminate a critical database daemon, a Docker proxy, or a core OS service. Suddenly your machine is freezing and you're wondering what just happened.
I got tired of that workflow and built PortIntel — a cross-platform port intelligence tool with embedded offline ML, a safety override engine, and a clean visual UI. Here is a deep dive into how it works.
What is PortIntel?
PortIntel is an offline-first, cross-platform port intelligence tool and safe process termination supervisor built with Tauri v2 (Rust) and React/TypeScript.
Unlike a generic port scanner, it embeds an offline Decision Tree ML classifier directly into the Rust binary that evaluates every active socket and tells you:
- Importance Category — Is this port running a system-critical service, a dev workload, or something unknown/suspicious?
- Termination Safety — Is it safe to kill this process, or will doing so crash your system?
The Architecture
PortIntel uses a clean decoupled architecture — a React frontend talking to a Tauri/Rust backend over IPC:
┌─────────────────────────────────────┐
│ React / TypeScript UI │
│ (Vite + Tailwind CSS) │
└───────────────┬─────────────────────┘
│ Tauri IPC Commands
┌───────────────▼─────────────────────┐
│ Rust Backend (Tauri v2) │
│ │
│ ┌─────────────────────────────┐ │
│ │ Socket Scanner │ │
│ │ netstat/tasklist (Windows) │ │
│ │ lsof (macOS / Linux) │ │
│ ├─────────────────────────────┤ │
│ │ ONNX ML Classifier │ │
│ │ (tract-onnx, fully offline)│ │
│ ├─────────────────────────────┤ │
│ │ Safety Override Engine │ │
│ │ (hard-coded kernel guards) │ │
│ ├─────────────────────────────┤ │
│ │ HTTP Daemon (tiny_http) │◄───┼── Browser Extension / CLI
│ │ http://127.0.0.1:12200 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
The ML Classifier — 100% Offline Inference
This is the core of PortIntel. Instead of a dumb blocklist, every active socket is evaluated by a Decision Tree Classifier trained in Python (scikit-learn) and compiled directly into the Rust binary using tract-onnx.
Feature Vector
For each active socket, a 4-dimensional feature vector is constructed:
x = [
port_number, // e.g. 5173, 5432, 80
is_system_user, // 0 or 1 (root/SYSTEM)
process_category_index,// 0–18 (mapped from process name)
operating_system // 0 = macOS/Linux, 1 = Windows
]
Two Output Models
Model 1 — Importance Classification:
| Label | Meaning |
|---|---|
0 — CRITICAL |
System-level services (RPC, spooler, resolver) |
1 — DEVELOPMENT |
Dev servers, local DBs, Node/Vite/Django |
2 — UNKNOWN |
Unidentified, non-standard bindings |
Model 2 — Termination Safety:
| Label | Meaning |
|---|---|
0 — SAFE_TO_KILL |
Safe to terminate to free port resources |
1 — DANGEROUS_TO_KILL |
Termination could destabilize the system |
Training the Model
The model training pipeline is straightforward:
pip install numpy scikit-learn skl2onnx
python train_model.py
This outputs two ONNX files directly into src-tauri/assets/:
port_classifier_importance.onnxport_classifier_safety.onnx
These get compiled directly into the Tauri binary at build time — no external files, no cloud API, no network required.
The Safety Override Engine
Even if the ML model outputs SAFE_TO_KILL, a second hard-coded safety layer kicks in. The Rust backend checks every kill request against:
- System PIDs (typically ≤ 100) — always blocked
-
Core executables —
svchost.exe,lsass.exe,wininit.exe,services.exe,smss.exe,csrss.exe,winlogon.exe,spoolsv.exe,launchd,init - System/root users — sockets registered under system namespaces
If any of these match, the Kill button is disabled in the UI entirely. Instead, the user sees a contextual advisory suggesting safer alternatives (gracefully stopping a service, pausing a Docker container, etc.).
This dual-layer approach — ML + hard overrides — ensures PortIntel never causes a BSOD or system freeze.
Key Features
Comprehensive Socket Scanning
Real-time detection of active TCP/UDP bindings on all platforms:
-
Windows:
netstat+tasklist -
macOS/Linux:
lsof
Project-Centric Workload Grouping
Ports are automatically categorized into logical groups:
| Category | Examples |
|---|---|
| Web Dev | Vite (:5173), Next.js (:3000), React DevServer |
| Databases | PostgreSQL (:5432), MySQL (:3306), Redis (:6379) |
| Docker | Container proxies, daemon sockets |
| System Daemons | RPC, spooler, Bonjour, DNS resolver |
| Utilities | Language servers, build tools |
Offline Diagnostic Advisor Panel
Every port has a detail-rich inspector showing:
- Socket context and process category
- ML-based security assessment
- OS-native command alternatives to stop the process safely
Background HTTP API Daemon
When running, PortIntel spins up a micro HTTP server at http://127.0.0.1:12200 — enabling browser extensions, CLI tools, and custom dashboards to query live port data.
Available endpoints:
# Get all active ports
GET /ports
# Analyze a specific socket
POST /analyze
{ "port": 3000, "processName": "node", "isSystem": false }
# Kill a process (subject to safety checks)
POST /kill
{ "pid": 14201 }
Example /analyze response:
{
"category": "Dev Server",
"importance": "DEVELOPMENT",
"safety": "SAFE_TO_KILL",
"reasoning": "User development environment or application server. Safe to terminate to free up port resources."
}
Dynamic Theme Engine
Built with a fully responsive glassmorphic UI supporting Light, Dark, and System theme switching using Tailwind CSS's selector strategy with smooth CSS transitions.
Tech Stack
| Layer | Technology |
|---|---|
| UI Framework | React 18, TypeScript, Vite |
| Styling | Tailwind CSS, Lucide Icons |
| Desktop Shell | Tauri v2 (Rust) |
| ML Inference |
tract-onnx (compiled into binary) |
| Model Training | Python 3.10+, scikit-learn, skl2onnx
|
| HTTP Daemon |
tiny_http, serde_json
|
Getting Started
# 1. Clone the repo
git clone https://github.com/Laksopan23/PortIntel.git
cd PortIntel
# 2. Install dependencies
npm install
# 3. (Optional) Retrain the ML models
pip install numpy scikit-learn skl2onnx
python train_model.py
# 4. Run in development mode
npm run tauri dev
# 5. Build a production installer
npm run tauri build
Prerequisites: Node.js v18+, Rust (via rustup), Python 3.10+ (only for model retraining)
What I Learned Building This
A few things that made this project genuinely interesting to build:
Embedding ML in Rust — Converting a scikit-learn model to ONNX and loading it inside a Rust binary with tract-onnx was a surprisingly smooth pipeline. The model adds zero startup latency and runs inference in microseconds.
Tauri IPC patterns — Designing a clean command interface between the React frontend and Rust backend forced me to think carefully about data contracts and error surfaces.
Cross-platform syscalls — Handling the difference between netstat/tasklist on Windows and lsof on Unix inside a single Rust codebase required careful output parsing and OS detection logic.
CSS theming without FOUC — Building a robust light/dark/system switcher in Tailwind that avoids a flash-of-unstyled-content required some careful class injection timing in the Tauri shell.
Try It Out
The project is fully open source. If you have hit the EADDRINUSE wall one too many times, give it a try:
👉 https://github.com/Laksopan23/PortIntel
If you find it useful, a ⭐ on GitHub goes a long way. And if you have ideas for improvements — cross-platform installers, a VS Code extension, better process grouping heuristics — PRs and issues are very welcome.
Drop a comment below with how you currently handle port conflicts. I am curious what workflows other developers have.





Top comments (0)