Skip to content

Repository files navigation

portiye

Find what's using a port, and stop it

CI License: MIT Built with Tauri 2 Platforms Languages

The Ports tab: devices, system gauges, and every listening port with the process and project behind it

portiye is a free, open-source, cross-platform desktop app that shows every listening port on your computer, which process owns it, and which project that process was started from — and lets you kill it in one click. It runs from the menu bar / system tray on macOS, Linux and Windows, and also manages the Android emulators, iOS simulators, Docker containers and build daemons that opened half of those ports in the first place.

It is a graphical answer to lsof -i :3000, netstat -ano and EADDRINUSE: address already in use — with a confirmation dialog that names exactly what is about to die.


Contents

Why

You run npm run dev and get Error: listen EADDRINUSE: address already in use :::3000. Something is on port 3000. You do not know what, and you have four terminals open.

The usual path is lsof -i :3000, squint at a PID, kill -9 it, discover the real server was a child of the thing you killed and is still holding the port. portiye collapses that into: open the menu bar, read the row that says :3000 · node · ~/dev/shop, click Kill. Its children go with it.

Then multiply that by the six stray node, python and JVM processes still running from yesterday.

What it does

  • Lists every listening port, grouped by process family. emulator and the qemu it spawned are one row, not two, and killing the row takes the whole tree down — no orphaned server left holding the port.

  • Says who owns it. The .app bundle, the AVD, or the project directory a process was started from. ~/dev/shop beats a bare node.

    Ports nested under the process that started them: an IDE, its language servers and its helper, each on its own port
  • Fast Kill. One click clears every stray node, python, JVM, .NET, Go, Ruby, PHP, Rust or Dart process, with a confirmation that names each one.

  • Guardrails before anything dies. Databases (postgres, mysqld, mongod, redis), editors and IDEs, OS services and container hosts each carry an explicit warning into the confirmation. Nothing is ever killed silently.

  • Elevation when the OS refuses. Retries under sudo / UAC / polkit, and says which one is about to ask.

  • Port history. What opened, what closed, and when a different process took a port over — recorded while the window is closed.

    The History tab: ports opening and closing over time, filterable by event
  • Emulators, simulators, containers, daemons. Android AVDs, iOS simulators, Docker containers, Ollama models and JVM build daemons: start, stop, restart, wipe.

  • Live device logs. simctl log stream and adb logcat, filtered, copyable, exportable.

  • Export. JSON or CSV snapshot of what is listening, to ~/Downloads.

  • 28 languages, right-to-left included — see Languages.

  • Start at login, toggled from the toolbar.

  • No telemetry, no account, no network calls. It reads your machine and that is all.

The window is optional

portiye lives in the menu bar. The load readout, the listening ports grouped into families, and the devices are all reachable — and killable — without opening anything.

The menu bar menu: a one-line CPU, GPU, RAM and disk readout above the ports and devices submenus

Everything can be switched off

A gauge that is off is never measured: GPU off means no probe on the scan tick and no nvidia-smi sampler, devices off means simctl, adb and docker are never run at all.

The Settings tab: switches for every panel, column, gauge and menu bar element

Install

Download the installer for your platform from Releases.

Platform File Notes
macOS 10.13+ (Apple silicon & Intel) .dmg Unsigned — see below
Windows 10 / 11 .msi or -setup.exe Unsigned — see below
Linux .deb, .rpm, .AppImage needs lsof

The builds are not code-signed: signing certificates cost money per year and this app takes none. Every release is built in the open by release.yml from the tag you can read, so you can also just build it yourself.

macOS. Gatekeeper will refuse the first launch. On macOS 15 (Sequoia) and later, open it once, then go to System Settings → Privacy & Security and click Open Anyway. On macOS 14 and earlier, right-click the app → Open. Either way, this also works:

xattr -dr com.apple.quarantine /Applications/portiye.app

Windows. SmartScreen shows "Windows protected your PC" — click More info → Run anyway.

Linux. .deb and .rpm pull in lsof themselves. The .AppImage cannot declare dependencies, so install lsof first (apt install lsof, dnf install lsof, pacman -S lsof) — without it the port list stays empty.

Prefer to build it? See Build from source.

Common tasks

Find out what is running on port 3000

Open portiye, type 3000 in the filter. The row shows the port, the process name, the directory it was launched from, its memory, and its PID.

The terminal equivalents, for reference:

lsof -nP -iTCP:3000 -sTCP:LISTEN
netstat -ano | findstr :3000

Kill the process using a port

Click Kill on the row. portiye also kills whatever that process spawned, which is the part kill -9 <pid> gets wrong — killing a npm run dev or dotnet watch on its own leaves the real server running and orphaned, still holding the port.

Kill every Node.js (or Python, or JVM) process at once

A Node project shows up as node, vite, esbuild, next-server and nodemon all at once, so grouping by executable name never gathers it. Fast Kill has a Node.js chip that sweeps all of them, and the confirmation lists every PID first.

Free a port without opening the window

The menu-bar / tray menu lists the ports on its own. Click one, it dies.

Stop an Android emulator or iOS simulator

The Devices panel, or the tray menu. Restart keeps the data; Wipe / Erase does not, and says so before you agree.

How it compares to lsof, netstat and Activity Monitor

portiye lsof / netstat Activity Monitor / Task Manager
Shows listening ports yes yes Windows: partly; macOS: no
Says which project a process belongs to yes no no
Kills child processes too yes no no
Warns before killing a database or your editor yes no no
Groups a process tree into one row yes no partly
Records port takeovers over time yes no no
Manages emulators / containers yes no no
Works without a terminal yes no yes
Cross-platform, one interface yes different flags per OS no

portiye does not replace lsof for scripting. It replaces the twelve seconds of squinting between "something is on the port" and "it is gone".

FAQ

Is portiye free?

Yes. MIT licensed, no paid tier, no account.

Does it send anything over the network?

No. There is no telemetry, no update ping, no analytics. It reads local process and socket state and writes only when you export a file.

Which operating systems does it support?

macOS, Linux and Windows, from one codebase. macOS is the daily driver; Linux and Windows are compiled and tested in CI.

Do I need sudo or admin rights?

Not for your own processes. When the OS refuses — a process owned by another user — portiye offers to retry with elevation and tells you which prompt is about to appear.

Is it safe to kill a process from here?

For dev servers, yes: that is what it is for. Databases, editors, OS services and container hosts carry an explicit warning into the confirmation, and every destructive action lists exactly what it will affect before you agree. Nothing happens without a click.

Why did it kill more processes than I selected?

Because the one you selected spawned them. A npm run dev supervises the real server; killing the supervisor alone leaves the port occupied. The confirmation says "Processes they started are killed too."

What is a "family" in the port list?

A process and its listening descendants, collapsed into one row — emulator plus the qemu it spawned, or adb plus its server. Sorting by Group orders by how many processes belong together.

Does it work with Docker, WSL, or Podman?

Docker containers appear in the Runtimes panel with start / stop / remove. Ports published by a container appear in the port list like any other listener. Podman and Colima are recognised as container hosts for the purpose of kill warnings. WSL: ports forwarded to Windows appear; processes inside the VM are managed inside it.

How is this different from the kill-port npm package?

kill-port frees a port you already know about, from a script. portiye is for the moment you do not know what is on the port, do not know what killing it will take down, and would rather see it than guess.

Does it run in the background?

It lives in the menu bar / system tray. Closing the window keeps it running; the scanner keeps recording history. Quit from the tray menu to stop it.

How much does it cost to run?

One scan every five seconds, shared by the window, the tray and the history. Device enumeration (simctl list, docker ps) runs on a slow 30-second timer instead, because those shell out and cost real time.

Languages

English · العربية · አማርኛ · বাংলা · Deutsch · Español · فارسی · Filipino · Hausa · עברית · हिन्दी · Bahasa Indonesia · Қазақша · Кыргызча · Bahasa Melayu · Nederlands · Português (Brasil) · Русский · Kiswahili · ไทย · Türkmençe · Türkçe · اردو · Oʻzbekcha · Tiếng Việt · Yorùbá · 中文 · isiZulu

Arabic, Hebrew, Persian and Urdu mirror the entire layout. The app picks your system language on first run and remembers what you choose after that.

Adding a language

One file per language in src/locales/, plus a row in src/locales/index.ts:

cp src/locales/en.ts src/locales/xx.ts   # then translate the values

Set rtl: true in the registry row for a right-to-left language; the layout mirrors itself from there, because the stylesheet uses logical properties rather than left and right.

The thirteen strings in the menu-bar menu live separately in src-tauri/src/i18n.rs — the tray is native and cannot read the webview's table. npm run check verifies that no locale has a typo'd key or a dropped {placeholder}, and cargo test that no tray table is missing a string.

Missing keys fall back to English, so a partial translation still ships a working app. Translation fixes are the easiest contribution to make here.

Build from source

Prerequisites: Rust, Node 20+, and the Tauri system dependencies for your platform.

git clone https://github.com/mustafasavul/portiye.git
cd portiye && npm install
npm run tauri dev          # the real app
npm run tauri build        # a bundle in src-tauri/target/release/bundle

Tests and checks:

cd src-tauri && cargo test
npm run check

npm run dev renders the UI in Chromium alone — fast for styling, but it is not the engine the app ships on. Verify anything behavioural in npm run tauri dev.

How it works

One poller, in Rust. watch.rs scans every five seconds, diffs the snapshot, records history and emits ports-changed; the window and the tray both read its cache instead of scanning for themselves. That single System instance is also what makes the CPU percentages real — sysinfo needs two samples of the same instance to compare.

Ports come from lsof on macOS and Linux and netstat on Windows, joined with process metadata from sysinfo. The UI is React 19 + TypeScript in a Tauri 2 webview — a native WebView rather than a bundled Chromium, so the whole app is a few tens of megabytes rather than a few hundred.

Everything else is in CLAUDE.md: the layout, the decisions worth not re-litigating, and the traps that cost real debugging time.

Contributing

Issues, translations and small focused pull requests are welcome — see CONTRIBUTING.md. By participating you agree to the Code of Conduct. Security reports go through SECURITY.md, privately.

License

MIT © Mustafa Savul


portiye is a port manager, port monitor and process killer for developers — an open-source GUI alternative to lsof -i, netstat -ano, ss -ltnp, fuser -k, kill -9 and npx kill-port. It answers "what is running on port 3000", "how do I fix EADDRINUSE / address already in use", "which process is using this port on macOS, Windows or Linux", and "how do I kill a stuck dev server and its children". Menu bar app · system tray app · Tauri · Rust · React · macOS · Linux · Windows · Android emulator manager · iOS simulator manager · Docker container manager.

About

Find what's using a port and stop it. Menu-bar app for listening ports, the processes behind them, and the emulators, simulators and containers that opened them. macOS, Linux, Windows.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages