<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Francesco</title>
    <description>The latest articles on DEV Community by Francesco (@fran-mora).</description>
    <link>https://dev.to/fran-mora</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3784108%2Ff14b062e-e7ea-49ef-9573-01fce50e466b.jpeg</url>
      <title>DEV Community: Francesco</title>
      <link>https://dev.to/fran-mora</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fran-mora"/>
    <language>en</language>
    <item>
      <title>Port Collision Radar – macOS menubar app that watches your listening TCP ports</title>
      <dc:creator>Francesco</dc:creator>
      <pubDate>Sat, 21 Feb 2026 16:08:56 +0000</pubDate>
      <link>https://dev.to/fran-mora/port-collision-radar-macos-menubar-app-that-watches-your-listening-tcp-ports-eea</link>
      <guid>https://dev.to/fran-mora/port-collision-radar-macos-menubar-app-that-watches-your-listening-tcp-ports-eea</guid>
      <description>&lt;h1&gt;
  
  
  I built a radar for your ports
&lt;/h1&gt;

&lt;p&gt;Every developer has been there. You run &lt;code&gt;npm start&lt;/code&gt; and get hit with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: listen EADDRINUSE: address already in use :::3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You sigh. You run &lt;code&gt;lsof -i :3000&lt;/code&gt;. You kill the rogue process. You move on with your life — until it happens again tomorrow.&lt;/p&gt;

&lt;p&gt;I got tired of this. So I built &lt;strong&gt;Port Collision Radar&lt;/strong&gt;, a macOS menubar app that watches your listening TCP ports in real-time and tells you the moment something takes over a port it shouldn't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5jtr8hd731ixil98px3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5jtr8hd731ixil98px3.gif" alt="Port Collision Radar demo" width="400" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually does
&lt;/h2&gt;

&lt;p&gt;The app sits in your menubar and scans &lt;code&gt;lsof&lt;/code&gt; every 4 seconds. It tracks which process owns which port. When ownership changes — say, a zombie Node process grabs port 3000 before your dev server can — it flags it as a &lt;strong&gt;collision&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are two views:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Radar view&lt;/strong&gt; — a circular visualization where ports appear as color-coded dots. Inner ring is well-known ports (0–1023), middle ring is registered ports (1024–49151), outer ring is ephemeral. The dots are colored by process, so you can instantly see clustering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List view&lt;/strong&gt; — a searchable table with port numbers, process names, PIDs, and status.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Collisions pulse red. New ports glow yellow. Everything else is calm cyan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a radar?
&lt;/h2&gt;

&lt;p&gt;Because staring at &lt;code&gt;netstat&lt;/code&gt; output is miserable. I wanted something I could glance at in my menubar and immediately know if something was wrong. The radar metaphor clicked — ports are "out there" on your system, and you're scanning for them.&lt;/p&gt;

&lt;p&gt;It's also just... fun? There's something satisfying about watching your ports orbit on a little radar while you work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;It's dead simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Electron&lt;/strong&gt; + &lt;strong&gt;menubar&lt;/strong&gt; npm package for the macOS menubar integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vanilla JS&lt;/strong&gt; — no React, no framework, no build tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canvas API&lt;/strong&gt; for the radar animation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lsof&lt;/strong&gt; for port scanning (the same tool you'd use in the terminal)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;electron-builder&lt;/strong&gt; for packaging as a signed + notarized universal dmg&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entire app is ~600 lines of code across 6 files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap fran-mora/homebrew-tap
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; port-collision-radar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or grab the &lt;code&gt;.dmg&lt;/code&gt; from &lt;a href="https://github.com/fran-mora/port-collision-radar/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The source is open: &lt;a href="https://github.com/fran-mora/port-collision-radar" rel="noopener noreferrer"&gt;github.com/fran-mora/port-collision-radar&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;A few ideas I'm considering for v2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker container port mapping awareness&lt;/li&gt;
&lt;li&gt;Network-wide scanning (not just localhost)&lt;/li&gt;
&lt;li&gt;Historical port usage timeline&lt;/li&gt;
&lt;li&gt;Notifications when specific ports get claimed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of those sound useful, let me know — or open an issue.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with frustration and Electron by &lt;a href="https://github.com/fran-mora" rel="noopener noreferrer"&gt;Francesco Moramarco&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>electron</category>
      <category>macos</category>
    </item>
  </channel>
</rss>
