The Problem: EADDRINUSE
Every developer knows this error:
Error: listen EADDRINUSE: address already in use :::3000
It happens when a dev server crashes without closing its sockets or when a node/bun process keeps running in the background.
The default fix is typing two separate commands:
lsof -i :3000
kill -9 <PID>
Or combining them into a bash snippet:
kill -9 $(lsof -t -i:3000)
This is tedious. On Windows, you have to use netstat -ano | findstr :3000 followed by taskkill. Spawning lsof or netstat sub-processes also takes time and behaves differently on different operating systems.
I built kport to do one thing quickly: inspect socket tables directly and kill whatever is holding the port.
Direct Kernel Queries
Instead of calling external shell commands, kport reads socket bindings straight from the OS kernel:
- Linux: Reads
/proc/net/tcp,/proc/net/tcp6, and/proc/[pid]/fd. - macOS: Uses the
sysctlinterface (NET_RT_STAT) to resolve socket inodes to PIDs. - Windows: Calls
GetExtendedTcpTableviaiphlpapi.dll.
Querying socket state directly takes less than 2 milliseconds.
pub fn find_process_on_port(port: u16) -> Result<Option<ProcessInfo>, KportError> {
#[cfg(target_os = "linux")]
return linux::get_port_owner(port);
#[cfg(target_os = "macos")]
return macos::get_port_owner(port);
#[cfg(target_os = "windows")]
return windows::get_port_owner(port);
}
Dual Publishing: Cargo + NPM
I wanted kport to be accessible whether someone works in Rust or JavaScript.
Rust via Cargo
cargo install kport
JS/TS via Bun or NPX (Zero Install)
Node developers don't always have Cargo installed, but they do have npm or bun.
Publishing @neuralshyam/kport on NPM allows zero-install execution:
bunx @neuralshyam/kport 3000
npx @neuralshyam/kport 3000
The NPM package isn't written in JavaScript with Node overhead. It contains a tiny JS wrapper script. On postinstall (or first run), it downloads the matching native binary compiled for darwin-arm64, linux-x64, or win32-x64.
Interactive TUI Mode
Running kport without arguments opens a terminal dashboard:
kport
┌────────────────────────────────────────────────────────────────────────┐
│ kport v0.2.2 - Active Ports │
├────────┬────────┬──────────────────────┬─────────────┬─────────────────┤
│ PORT │ PID │ PROCESS │ MEMORY │ STATUS │
├────────┼────────┼──────────────────────┼─────────────┼─────────────────┤
│ 3000 │ 41829 │ node (next-dev) │ 142 MB │ LISTENING │
│ 5432 │ 1102 │ postgres │ 38 MB │ LISTENING │
│ 6379 │ 1250 │ redis-server │ 12 MB │ LISTENING │
│ 8080 │ 88210 │ bun (api) │ 24 MB │ LISTENING │
└────────┴────────┴──────────────────────┴─────────────┴─────────────────┘
[Up/Down] Select [Space] Mark [K] Kill [F] Force Kill [Q] Quit
The TUI uses crossterm and ratatui for fast rendering and keyhandling.
Other Features
- Port ranges & wildcards:
kport 5000..5010 "80*" - HTTP/TCP probing:
kport --probe 3000 - Orphan process sweep:
kport --zombies
Links
- NPM:
@neuralshyam/kport - Crates.io:
kport - GitHub:
github.com/neuralshyam/kport