[HN Gopher] Show HN: Sonar - A tiny CLI to see and kill whatever...
       ___________________________________________________________________
        
       Show HN: Sonar - A tiny CLI to see and kill whatever's running on
       localhost
        
       Author : raskrebs
       Score  : 121 points
       Date   : 2026-03-20 09:59 UTC (13 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | raskrebs wrote:
       | 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.
        
         | pluc wrote:
         | Have a look at Evan Hahn's murder util:
         | https://codeberg.org/EvanHahn/dotfiles/src/commit/843b9ee13d...
        
           | raskrebs wrote:
           | Will check it out
        
           | 0cf8612b2e1e wrote:
           | 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'
        
         | embedding-shape wrote:
         | > 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.
        
           | msdz wrote:
           | > 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/
        
       | Bradd3rs wrote:
       | love this, i get tired of spamming lsof -i tcp:xxxx
        
         | raskrebs wrote:
         | 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.
        
         | Doublon wrote:
         | The README made me realize I just needed a simple `alias local-
         | tcp-listeners='lsof -iTCP -sTCP:LISTEN'` in my
         | `~/.bash_aliases` :)
        
           | deadbabe wrote:
           | Same, not sure why a whole cli app is needed.
        
             | paddim8 wrote:
             | Because it gives more context. Quite obvious if you look at
             | the readme...
        
             | raskrebs wrote:
             | Developers 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 wrote:
           | 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.
        
       | klaushardt wrote:
       | 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:3001
        
         | raskrebs wrote:
         | Good point. Could you add an issue, then i'll have a chance to
         | look into it :)
         | 
         | https://github.com/RasKrebs/sonar/issues
        
       | frankdenbow wrote:
       | love this, happens too often
        
         | raskrebs wrote:
         | Exactly, really hates it as well. Please post any issues you
         | may have
        
       | moezd wrote:
       | Sonar as in SonarQube? That's an interesting choice for a name :)
        
         | beart wrote:
         | How about Sonar as in SOund Navigation And Ranging?
        
         | raskrebs wrote:
         | 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.
        
       | chwzr wrote:
       | 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 wrote:
         | 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 wrote:
           | Its funny bc the title suggests a tool for listing and
           | killing
        
             | raskrebs wrote:
             | True, 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 wrote:
               | Why not grep the output to abother tool?
        
             | tomcatfish wrote:
             | HN is a place where people can be expected to go _beyond_
             | the title (though I like the limited script and am glad it
             | was posted). Misleading titles are not uncommonly flagged
             | and changed, even.
        
       | pdimitar wrote:
       | 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 wrote:
         | Glad to hear! Please join the party and post any issues you
         | have.
        
       | clutchski wrote:
       | Mine is called "porthole"
       | 
       | https://github.com/clutchski/dotfiles/blob/main/home/bin/por...
        
         | raskrebs wrote:
         | Any features you are missing or ideas for the use case?
        
         | Brainspackle wrote:
         | you picked a unique name. There is already a massively popular
         | product called Sonar
        
       | mfkrause wrote:
       | 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 wrote:
         | 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
        
       | maciejj wrote:
       | 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 wrote:
         | 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:
         | 
         | https://github.com/RasKrebs/sonar/issues/15
        
       | RonanSoleste wrote:
       | I just have an alias in my .bashrc :)
        
         | raskrebs wrote:
         | 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 wrote:
           | 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 wrote:
             | Probably 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 wrote:
               | That monitor sounds interesting; I manually set something
               | up in Keyboard Maestro to notify me that something quit
               | and potentially re-launch it.
        
               | raskrebs wrote:
               | Have 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
        
       | quotemstr wrote:
       | 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.
        
         | formerly_proven wrote:
         | > So why doesn't everyone run local services over Unix sockets?
         | 
         | > The only problems:
         | 
         | 3) 40 years of Windows not supporting UDS.
        
           | quotemstr wrote:
           | Yeah, 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 wrote:
             | Yeah, 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 wrote:
         | 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.
        
       | jkestner wrote:
       | I read the readme. :) Very nice. Thoughtful features. Get this on
       | Homebrew!
        
         | raskrebs wrote:
         | I will, but the process is a bit tedious. But will look into it
         | over the weekend
        
           | 0x457 wrote:
           | I recommend just doing a tap in the same repo rather than
           | adding this to homebrew first.
        
       | fcoury wrote:
       | 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.
       | 
       | https://github.com/fcoury/sonars
        
         | raskrebs wrote:
         | 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 wrote:
           | I did this more as an experiment but man it sucks, doesn't
           | it?
        
             | raskrebs wrote:
             | What sucks? Software distillation? :)
        
         | zenoprax wrote:
         | 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.
        
       | kohexo wrote:
       | 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 wrote:
         | 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 :)
        
       | mustafa0x wrote:
       | 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 wrote:
         | Will have a look. Mind creating an issue so i don't forget?
         | 
         | https://github.com/raskrebs/sonar/issues
        
       | mrbonner wrote:
       | Hey, 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 wrote:
         | I 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 wrote:
           | I 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 wrote:
       | Nice -- the use case for this is immediately obvious. I've spent
       | more time than I care to admit running `lsof -i :PORT` or
       | `netstat -tulpn | grep PORT` trying to figure out what's
       | squatting on a port before running a dev server. Having a clean
       | CLI for this with kill support is the kind of small tool that
       | earns a permanent spot in your toolkit. Added to my dotfiles
       | setup.
        
         | raskrebs wrote:
         | Great to hear! Please add any issues or feature request if you
         | find anything missing :)
        
         | zephyreon wrote:
         | Ditto. Though I always take the lazy route and just change port
         | numbers until I find an open one. My Mac is probably running
         | like 20 different localhost apps at any given time.
        
       ___________________________________________________________________
       (page generated 2026-03-20 23:01 UTC)