6 ms·
Show HN: Sonar – A tiny CLI to see and kill whatever's running on localhost
- raskrebs 7mo agoI 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.
- pluc 7mo agoHave a look at Evan Hahn's murder util: https://codeberg.org/EvanHahn/dotfiles/src/commit/843b9ee13d949d346a4a73ccee2a99351aed285b/home/bin/bin/murder https://codeberg.org/EvanHahn/dotfiles/src/commit/843b9ee13d...
- raskrebs 7mo agoWill check it out
- 0cf8612b2e1e 7mo agoSold 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'
- embedding-shape 7mo 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.
- raskrebs 7mo ago[dead]
- msdz 7mo ago> that they're unable to [manage and] kill child processes they themselves spawn makes it seem like they have zero clue about what they're doing. Yeah, at the bare minimum these projects could also use something like portless[1] which literally maps ports to human- (and language model-)readable, named .localhost URLs. Which _should_ heavily alleviate assignment of processes to projects and vice versa, since at that point, hard-to-remember port numbers completely leave the equation. You could even imagine prefixing them if you've got that much going on for the ultimate "overview", like project1-db.localhost, project1-dev.localhost, etc. [1] https://port1355.dev/ https://port1355.dev/
- embedding-shape 7mo agoWell, or just use port 0 like we've done for decades, read what port got used, then use that. No more port collisions ever. I thought most people were already aware of that by now, but judging from that project even existing, seems I was wrong.
- hackerthemonkey 7mo agoThat’s a little different, right? Using port 0 would imply that clients have not hard coded what port they should connect to and also we don’t mind having duplicate processes occupying other ports which are no longer on active use
- Servant-of-Inos 7mo ago[dead]
- Bradd3rs 7mo agolove this, i get tired of spamming lsof -i tcp:xxxx
- raskrebs 7mo agoGlad 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.
- Doublon 7mo agoThe README made me realize I just needed a simple `alias local-tcp-listeners='lsof -iTCP -sTCP:LISTEN'` in my `~/.bash_aliases` :)
- deadbabe 7mo agoSame, not sure why a whole cli app is needed.
- paddim8 7mo agoBecause it gives more context. Quite obvious if you look at the readme...
- raskrebs 7mo agoDevelopers are nitpicky, atleast i am and i know a lot of others that are as well. So don't underestimate the value of a nice tool with good developer experience, one that's intuitive, clean and easy to use means a lot when juggling so many things during a workday. So having a clean and light implementation to make job even easier is in my opinion worth it (and thus needed) :)
- raskrebs 7mo agoTrue, 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.
- klaushardt 7mo agoWould 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:3001
- raskrebs 7mo agoGood point. Could you add an issue, then i'll have a chance to look into it :) https://github.com/RasKrebs/sonar/issues https://github.com/RasKrebs/sonar/issues
- frankdenbow 7mo agolove this, happens too often
- raskrebs 7mo agoExactly, really hates it as well. Please post any issues you may have
- moezd 7mo agoSonar as in SonarQube? That's an interesting choice for a name :)
- takahitoyoneda 7mo ago[dead]
- chwzr 7mo agoi 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 7mo agoI 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 7mo agoIts funny bc the title suggests a tool for listing and killing
- raskrebs 7mo agoTrue, it was what it started as, but grew as i found my self missing features. Got a few users and now i don't want to update the name. Also easy and quick to write in the terminal
- bartek_gdn 7mo agoWhy not grep the output to abother tool?
- pdimitar 7mo agoI 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 https://github.com/jkfran/killport
- raskrebs 7mo agoGlad to hear! Please join the party and post any issues you have.
- clutchski 7mo agoMine is called “porthole” https://github.com/clutchski/dotfiles/blob/main/home/bin/porthole https://github.com/clutchski/dotfiles/blob/main/home/bin/por...
- raskrebs 7mo agoAny features you are missing or ideas for the use case?
- Brainspackle 7mo agoyou picked a unique name. There is already a massively popular product called Sonar
- olivercoleai 7mo ago[dead]
- mfkrause 7mo agoI 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 7mo agoI 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
- maciejj 7mo agoNice! 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 7mo ago[dead]
- raskrebs 7mo agoSomeone 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: https://github.com/RasKrebs/sonar/issues/15 https://github.com/RasKrebs/sonar/issues/15
- maciejj 7mo agoCool, will check
- RonanSoleste 7mo agoI just have an alias in my .bashrc :)
- raskrebs 7mo agoTry 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 7mo agoCan 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 7mo agoProbably not, that's what makes it so lean (it doesn't really pull in anything). Although i have a feature branch with a tray app (for macos) that let's you monitor and track any process (will send notifications when one goes up or down). But it's just gimmicks i felt i needed to make life a bit easier when working with compose and across worktrees
- Barbing 7mo agoThat monitor sounds interesting; I manually set something up in Keyboard Maestro to notify me that something quit and potentially re-launch it.
- raskrebs 7mo agoHave a look at this issue, and the picture i posted. Their is an explanation on how to test it out locally if you wish too https://github.com/raskrebs/sonar/issues/15 https://github.com/raskrebs/sonar/issues/15
- quotemstr 7mo agoChrist 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.
- formerly_proven 7mo ago> So why doesn't everyone run local services over Unix sockets? > The only problems: 3) 40 years of Windows not supporting UDS.
- quotemstr 7mo agoYeah, that too. Windows supports them nowadays too, just to be clear. I think we're still bottlenecked, right now, on #1 and #2 in the form of Java 8 refusing to die.
- formerly_proven 7mo agoYeah, doing the math it's actually only 33 years of not supporting AF_UNIX, but that's not really right either, since those versions of Windows didn't support any sockets. I guess the technically correct answer then is that Windows didn't support UDS for 26 years. Which is still enough for most portable software to go "eh, localhost is fine*" * resolving localhost is actually a pretty bad idea (yet very common) and it's way more robust to listen directly on a numeric address.
- 0x457 7mo agoSome 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.
- jkestner 7mo agoI read the readme. :) Very nice. Thoughtful features. Get this on Homebrew!
- fcoury 7mo agoWe 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. https://github.com/fcoury/sonars https://github.com/fcoury/sonars
- raskrebs 7mo agoYou 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 7mo agoI did this more as an experiment but man it sucks, doesn't it?
- raskrebs 7mo agoWhat sucks? Software distillation? :)
- fcoury 7mo agoYes, instead of everybody contributing to one central codebase, we now have the same concept being rewritten a thousand times :-)
- raskrebs 7mo agoAhhh yes sure, but not too worried about that i think. Its not so difficult to create, but to innovate and maintain requires participation. It can be the bulk of the job. But most def its sad if people leave their good ideas in a fork of their own. But also great that you can reproduce a good idea thats been conflated with wayy too much crap, because a product lost site of ehat their value proposition was
- 7mo ago
- aplomb1026 7mo ago[dead]
- kohexo 7mo agoHonestly, 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 7mo agoI 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 :)
- kohexo 7mo agoYeah, I had to create the script myself and used an extension so I could click a button in VS Action bar. Once I outgrow my current setup, this is probably what I'm migrating to.
- mustafa0x 7mo agoNice 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/prompts https://github.com/bombshell-dev/clack/tree/main/packages/pr...
- raskrebs 7mo agoWill have a look. Mind creating an issue so i don't forget? https://github.com/raskrebs/sonar/issues https://github.com/raskrebs/sonar/issues
- abitabovebytes 7mo ago[dead]
- mrbonner 7mo agoHey, thanks for sharing this. Your app inspires me to take a look at Go, again! I've been searching for another primary language to learn. My primary used to be Java at $day$ job and now Python for ML/AI. I love Python but still feel insecure given the lack of static typing. I look at TypeScript as well, especially in the context of Bun runtime. I decided it may not be for me, not the language, but the ecosystem around it.
- raskrebs 7mo agoI quite like go for how lean it is, really nice for local projects with lots of constant changes. Also easy to learn. The biggest most annoying thing is how bad error handling is done, not sure why they built it like that. I primarily write typescript and python for work. But have dabbled in bunch of other languages at different jobs and for different tasks. Yet to pick up rust, but have been wanting to. But tend to pick what seems most right for the task, while also considering what i most want to be working with
- mrbonner 7mo agoI forgot that I also "try" Rust as well. But, I feel like it may not be suitable for my use cases and not simple enough for non-intelligent person like me :-). I agree error handling in Go could be better. But, comparing to Java I don't think I would feel salty.
- diablevv 7mo ago[flagged]
- rrojas-nexus 7mo ago[dead]
- koinedad 7mo agoI run lsof a good amount. This is a great idea.
- deleted 7mo ago[deleted]
- derodero24 7mo ago[flagged]
- spl757 7mo agoctop is great for docker containers
- derodero24 7mo ago[flagged]
- cyanydeez 7mo agoShould git relos with CLI tools have opencode skills directory?
- oweiler 7mo agohttps://github.com/helpermethod/pk/blob/main/pk https://github.com/helpermethod/pk/blob/main/pk I have a tiny shell function to kill whatever is listening on that port
- maurice-nomad 7mo agonice
- FileForge 7mo agoDefinitely useful
- eddie-wang 7mo ago[dead]