# port-whisperer: a colour-coded table of everything listening on your ports

> port-whisperer is a Node command line tool that shows every process listening on a TCP port, with the framework detected, the project directory resolved, the uptime, a health colour, and interactive kill and log commands. It works by making three shell calls rather than by asking the kernel directly, which is why it starts in about a fifth of a second.

**LarsenCundric/port-whisperer** — A beautiful CLI tool to see what's running on your ports

- Repository: https://github.com/LarsenCundric/port-whisperer
- Stars: 881 · Forks: 67
- Language: JavaScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/larsencundric-port-whisperer

## The table, and the three questions it answers

port-whisperer is a command line tool to see what is running on your ports, and the problem it names is stopping to guess which process is hogging port 3000. The output is a colour-coded table of every dev server, database and background process listening on the machine, with columns for the port, the process, the PID, the project, the framework, the uptime and the status. The project column is the one that changes how you read it, because it is the working directory of the process rather than a guess, and the framework column tells you a node process on port 3000 is a Next.js app. The colours carry meaning too, with green for healthy, yellow for orphaned and red for zombie. The default view filters out system applications like Spotify and Raycast, and the footer tells you that running ports with a number gives details and that the --all flag shows everything. The package is MIT licensed, the primary language is JavaScript, and the version in the manifest is 1.5.0 with the last push on 2026-04-12.

## Installing it globally, or running it without installing

The install is a single npm command:

```bash
npm install -g port-whisperer
```

Or you can run it directly without installing anything:

```bash
npx port-whisperer
```

The package registers two binaries, ports and whoisonport, both pointing at the same entry script, so whoisonport is there for muscle memory from other tools. The README goes one step further and suggests asking Claude Code to run the install command for you and then using ports right away, with no setup steps. That detail tells you what kind of tool this is, a zero-configuration developer utility rather than something you integrate. The manifest is minimal, with three runtime dependencies, chalk for the colours, cli-table3 for the table and string-width for the column padding, and the engines field requires Node 18 or newer. The published files are just the src directory, and the only script is a start command that runs the entry file directly.

## Inspecting one port, and killing what you find

Asking about a specific port gives a detailed view rather than a row:

```bash
ports 3000
# or
whoisonport 3000
```

That view shows the full process tree, the repository path, the current git branch, the memory usage and an interactive prompt to kill the process. The git branch is the detail that makes it useful, because a port held by the wrong checkout of the right project is a common and confusing problem. Killing is available as a subcommand with several forms:

```bash
ports kill 3000                # kill by port
ports kill 3000 5173 8080      # kill multiple
ports kill 3000-3010           # kill a port range
ports kill 42872               # kill by PID
ports kill -f 3000             # force kill (SIGKILL)
```

The resolution is automatic, so a port is turned into a process for you, with a fallback to the PID if no listener matches. The -f flag sends SIGKILL and is there for a process that will not die gracefully, which in practice means something ignoring SIGTERM. Port ranges expand into individual kills, and empty ports in the range are silently skipped and reported in a summary line, so a range over a sparse block of ports does not produce a wall of errors.

## Logs are discovered through file descriptors, not configuration

The logs command is the most interesting piece of the tool, because it finds the log file without being told where it is. The commands are:

```bash
ports logs 3000               # show last 50 lines and exit
ports logs 3000 -f            # follow (stream new lines)
ports logs 3000 --lines 10    # show last 10 lines
ports logs 3000 --lines 10 -f # show last 10 then follow
ports logs 3000 --err         # stderr only
```

The discovery mechanism is lsof file descriptor detection, and the reasoning is practical. If stdout and stderr are redirected to a file, the tool finds that file and tails it, which is what a dev server started with output going to a file does. If there is no such file, it falls back to the system log, which is log show on macOS and journalctl on Linux. The stderr-only flag is the one to reach for when a process is failing and its errors are separated from its normal output.

## A ps for developers, and the cleanup command

The ps subcommand is described as a beautiful ps aux for developers, and it shows all running dev processes, not only the port-bound ones, with CPU percentage, memory, framework detection and a description column that guesses what the process is doing from its command line, for example a jest runner or a server script. Docker processes are collapsed into a single summary row rather than listed individually, which matters when you have a dozen containers up. The clean command finds and kills orphaned or zombie dev server processes, and it deliberately only targets dev runtimes such as node and python, so it will not touch your desktop apps. There is also a watch mode, which gives real-time monitoring and notifies you whenever a port starts or stops listening, which is the feature to use when a build is starting a server and you want to know the moment it is up. A final detail worth noting is that the project column can be empty, since the tool resolves the working directory and reports what it finds.

## Three shell calls, and a framework detector that reads package.json

The implementation is described in three steps, and it runs in about 0.2 seconds. First is lsof with the TCP listen filter, which finds all processes listening on TCP ports. Second is a single batched ps call, which retrieves the process details for all PIDs at once, namely the command line, uptime, memory, parent PID and status. Third is a single batched lsof call on the working directory descriptors, which resolves the working directory of each process, and that is what lets the tool detect the project and the framework. For Docker ports, a single docker ps call maps host ports to container names and images. Framework detection reads the package.json dependencies and inspects the process command lines, and it recognises Next.js, Vite, Express, Angular, Remix, Astro, Django, Rails, FastAPI and many others. The batching is the reason for the speed, since one call per process would be the slow version of the same idea.

## Conclusion

port-whisperer suits a developer who keeps several dev servers running and wants to know which project owns which port without remembering the process ids, and who wants the framework recognised rather than just the binary name. It does not suit a machine where lsof is unavailable or restricted, since the whole implementation rests on it. Before you rely on it, note that it filters system applications by default, so a port you are looking for may be missing until you pass the --all flag, and check that the process it offers to kill is the one you meant, because the kill command resolves a port to a process automatically.

## FAQ

### How do I install port-whisperer?

Run npm install -g port-whisperer, or use npx port-whisperer to run it without installing. The package registers two commands, ports and whoisonport, both pointing at the same script, and it needs Node 18 or newer.

### Why is the port I am looking for missing from the list?

System applications and desktop apps are filtered out by default, so a port held by something like Spotify or Raycast will not appear. Use the --all flag to include system services, desktop apps and everything else listening on the machine.

### How does port-whisperer find the log file for a process?

It uses lsof file descriptor detection. If stdout and stderr are redirected to a file, it finds and tails that file, and if no log files are found it falls back to the system log, which is log show on macOS and journalctl on Linux. The --err flag limits the output to stderr.

### Is it safe for port-whisperer to kill processes?

The kill command resolves a port to a process automatically and falls back to the PID if no listener matches, and it sends SIGTERM unless you pass -f for SIGKILL. The clean command only targets dev runtimes such as node and python, so it will not touch desktop apps, but you should still check the process it picked before letting it through.

## Sources

- [Issues](https://github.com/LarsenCundric/port-whisperer/issues)
- [LarsenCundric/port-whisperer on GitHub](https://github.com/LarsenCundric/port-whisperer)
- [License: MIT](https://github.com/LarsenCundric/port-whisperer/blob/main/LICENSE)
- [README](https://github.com/LarsenCundric/port-whisperer/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/larsencundric-port-whisperer
