Show HN: Sonar – A tiny CLI to see and kill whatever's running on localhost (github.com)
98 points by raskrebs 9 hours ago
mustafa0x an hour ago
Nice util. It should be possible to kill inline.
I like clack/prompts. See its multiselect API.
https://github.com/bombshell-dev/clack/tree/main/packages/pr...
raskrebs 37 minutes ago
Will have a look. Mind creating an issue so i don't forget?
klaushardt 7 hours ago
Would be nice to have a flag to customize the URL displayed for Docker containers. I connect to my host via Tailscale, but I can’t open links with localhost. It would be helpful to have a parameter that allows us to choose a network device or specify an IP address to display.
3000 wud (getwud/wud:latest) wud getwud/wud:latest 3000 http://localhost:3000
3001 dockhand (fnsys/dockhand:latest) dockhand fnsys/dockhand:latest 3000 http://localhost:3001raskrebs 5 hours ago
Good point. Could you add an issue, then i'll have a chance to look into it :)
fcoury 2 hours ago
We live in crazy times. I wanted to add a PID to the list for my personal use and since I use Rust way more than Go, I decided to one-shot one app, and Codex indeed one shotted it, wow.
zenoprax an hour ago
I'm tempted to one-shot this into a series of FISH abbreviations.
And I would want someone to use that to one-shot a python implementation. And on and on like a game of telephone until the context degrades so far that it becomes an entirely different program.
raskrebs 2 hours ago
You can add PID with the c-flag, e.g.
sonar list -c port,process,pid,type,url,container
or just show all columns:
sonar list --all-columns
But yeah, it's quite cool. I believe the future lies in software distillation, so cool to see it happen on my own project :D
fcoury 2 hours ago
I did this more as an experiment but man it sucks, doesn't it?
raskrebs 39 minutes ago
raskrebs 9 hours ago
I always have a bunch of local projects running, particularly during the weekend where I'm rarely working on one thing at a time. A big pain of mine was constantly running into port: Redis from one project blocking another, orphaned dev servers from old worktrees, Docker containers I forgot about. The usual fix is lsof -iTCP | grep ..., then figuring out what the PID actually is, then killing it. But I always forget the command, and it doesn’t really include all the information that I like.
So I built this lightweight CLI. Single binary, no dependencies. It shows everything listening on localhost with process names, Docker container info, clickable URLs etc.
Sure there are workarounds, but none that satisfied my need for a short, easily rememberable command. Also nothing really has the same satisfaction as running sonar kill 3000 — it just feels nice. I’ve already been approached by a few agent orchestration tools that have been struggling with the same thing. It's really useful when you have multiple agents running, but it's not built for just that use case, I have also find it handy when killing off all containers after a failed cleanup and so on. Also know that MCPs are dead and CLIs are the new thing in agentic coding, this might be a useful tool for Claude, particularly when a compose process exits before all containers are stopped.
Open for contributions, ideas and feedback.
embedding-shape 7 hours ago
> I’ve already been approached by a few agent orchestration tools that have been struggling with the same thing
Wow, this says more about the agent orchestration tool ecosystem than what you might think, that they're unable to kill child processes they themselves spawn makes it seem like they have zero clue about what they're doing.
Probably why my impression always end up with "Wow, what a vibe-coded mess" when I look through the source of all these harnesses, they don't seem engineered at all.
pluc 7 hours ago
Have a look at Evan Hahn's murder util: https://codeberg.org/EvanHahn/dotfiles/src/commit/843b9ee13d...
0cf8612b2e1e 2 hours ago
Sold on the name alone. It also has the API I never realized I needed
puts 'usage:'
puts 'murder 123 # kill by pid'
puts 'murder ruby # kill by process name'
puts 'murder :3000 # kill by port'raskrebs 6 hours ago
Will check it out
maciejj 4 hours ago
Nice! I always forget the lsof flags and end up googling them every time. Would be cool if it could run in the system tray and show what's running on your ports at a glance. Also, the name had me thinking SonarQube at first, might be worth considering a rename to avoid the confusion.
raskrebs 3 hours ago
Someone else added an issue about this, and i replied explaining how to run the feature branch, have a look and please add any ideas to the issue:
clutchski 5 hours ago
Mine is called “porthole”
https://github.com/clutchski/dotfiles/blob/main/home/bin/por...
Brainspackle 4 hours ago
you picked a unique name. There is already a massively popular product called Sonar
raskrebs 5 hours ago
Any features you are missing or ideas for the use case?
pdimitar 5 hours ago
I am absolutely installing this and starting to use it daily!
For the even less patient there's also this (not mine): https://github.com/jkfran/killport
raskrebs 5 hours ago
Glad to hear! Please join the party and post any issues you have.
RonanSoleste 3 hours ago
I just have an alias in my .bashrc :)
raskrebs 3 hours ago
Try and have a look at the readme, this adds a bit more functionality. Maybe some if it you'll find useful :)
Started with the same, but found my self wanting a bit more, so just built it
RonanSoleste 2 hours ago
Can it do things that existing tools build into my distro cannot? It looks to me like a convenience tool. Which is fine, but i see no need for it myself
raskrebs 2 hours ago
kohexo 2 hours ago
Honestly, pretty cool. I was wondering if something like this existed. Right now I have scripts to kill the ports I use consistently to avoid issues when developing. Kudos!
raskrebs 34 minutes ago
I looked around for a while, couldn't find anything. Someone posted about killport but never stumbled upon it. Has some features that are the same, but not all. From the reaction online people don't seem to know of other solutions like this, or have something they have made them selves in the .zshrc :)
mfkrause 5 hours ago
I always find myself going through my zsh history for `lsof`. Will definitely check this out, seems interesting (even though I'm generally reluctant of installing third-party tools for such jobs).
raskrebs 5 hours ago
I get that, i also often install some and forgot about them. But i felt that there was a big gap in managing multiple services running on localhost. It's pretty lightweight if that helps
moezd 6 hours ago
Sonar as in SonarQube? That's an interesting choice for a name :)
beart 5 hours ago
How about Sonar as in SOund Navigation And Ranging?
raskrebs 5 hours ago
I think a cli tool that detects objects beneath the surface is a pretty intuitive name, but i was also reluctant in the beginning. But they are pretty keen on always using the qube part, i believe theirs is sonar-qube.
quotemstr 3 hours ago
Christ Almighty I hate our industry practice of binding to some inscrutable port number on localhost. Unix domain sockets aren't that hard! They're secure against all sorts of attacks and more convenient to boot. Instead of connecting to a number, you connect to a file. An ordinary file, with an ordinary name you can mv, chmod, and rm. Boring on a good way.
So why doesn't everyone run local services over Unix sockets?
The only problems: 1) web browsers don't support AF_UNIX URI scheme, and 2) ancient versions of Java don't have built-in APIs for AF_UNIX sockets.
That's it. For these trivial reasons, we've beat our head against arbitrary opaque numbers for decades.
And so, for want of a nail, the Unix was lost.
0x457 3 hours ago
Some random daemon binding to 3000 because it's the express default drives me nuts. I either do a Unix socket, a pick any random port if it has to bind on a port.
formerly_proven 3 hours ago
> So why doesn't everyone run local services over Unix sockets?
> The only problems:
3) 40 years of Windows not supporting UDS.
jkestner 3 hours ago
I read the readme. :) Very nice. Thoughtful features. Get this on Homebrew!
raskrebs 2 hours ago
I will, but the process is a bit tedious. But will look into it over the weekend
0x457 2 hours ago
I recommend just doing a tap in the same repo rather than adding this to homebrew first.
Bradd3rs 8 hours ago
love this, i get tired of spamming lsof -i tcp:xxxx
Doublon 7 hours ago
The README made me realize I just needed a simple `alias local-tcp-listeners='lsof -iTCP -sTCP:LISTEN'` in my `~/.bash_aliases` :)
deadbabe 7 hours ago
Same, not sure why a whole cli app is needed.
paddim8 7 hours ago
raskrebs 6 hours ago
raskrebs 6 hours ago
True, but as i write their are workarounds, the problem is that they are unintuitive, difficult to remember and don't provide all that much usability beyond listing. So these lack useful features like getting process stats, killing ports easily without having to remember the the pid after lsof and so on. I often have to kill multiple process at once after a failed cleanup. If you are into agentic coding, then having your agent create a profile for all the processes it stats, which it can easily kill of when finished is a lot easier for me atleast.
Some features on the way are: next available port; wait (wait for a host to return a successful health check before proceeding - good for migrations etc.). And lots more. It's not just about listing running ports, but a tool for managing them.
But to each their own, that's what's lovely about the many options available. But if you have anything in relation to this you think is neat, feel free to open an issue. It may be able to convince you that a simple alias won't suffice.
raskrebs 8 hours ago
Glad to hear! Have quite a few ideas in mind so keep an eye out for some updates (one of the ideas is an easy update command). There's a couple of open enhancement ideas as well. Feel free to add any or contribute.
frankdenbow 6 hours ago
love this, happens too often
raskrebs 5 hours ago
Exactly, really hates it as well. Please post any issues you may have
chwzr 6 hours ago
i have this in my .zshrc which provides same functionality:
lk() {
if [ $# -eq 0 ]; then
local output=$(sudo lsof -iTCP -sTCP:LISTEN -n -P)
elif [ $# -eq 1 ]; then
local output=$(sudo lsof -iTCP -sTCP:LISTEN -n -P | grep -i --color=always $1)
else
echo "find and kill processes listening on ports. Usage: lk [pattern]"
return 1
fi
if [ -z "$output" ]; then
echo "No listening processes found."
return 0
fi
# Show header + results
echo "$(sudo lsof -iTCP -sTCP:LISTEN -n -P | head -1)"
echo "$output"
echo ""
# Extract unique PIDs (skip the header row if no grep was applied)
local pids=($(echo "$output" | awk '{print $2}' | grep -E '^[0-9]+$' | sort -u))
if [ ${#pids[@]} -eq 0 ]; then
echo "No PIDs found."
return 0
fi
echo "PIDs to kill: ${pids[*]}"
echo -n "Kill these ${#pids[@]} process(es)? [y/N] "
read -r confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
for pid in "${pids[@]}"; do
echo "Killing PID $pid..."
sudo kill -9 $pid
done
echo "Done."
else
echo "Aborted."
fi
}raskrebs 5 hours ago
I have added quite a lot of functionality beyond listing and killing ports. Please check out the readme, it may convince you to try it out.
fionic 5 hours ago
Its funny bc the title suggests a tool for listing and killing