<?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: Adeyomi Lawal</title>
    <description>The latest articles on DEV Community by Adeyomi Lawal (@adeyomi_lawal_8c61225e087).</description>
    <link>https://dev.to/adeyomi_lawal_8c61225e087</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%2F3583471%2F1160ad7d-880f-4e48-8b32-330e8f43563d.png</url>
      <title>DEV Community: Adeyomi Lawal</title>
      <link>https://dev.to/adeyomi_lawal_8c61225e087</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adeyomi_lawal_8c61225e087"/>
    <language>en</language>
    <item>
      <title>Building a Cross-Platform CLI Tool with TypeScript</title>
      <dc:creator>Adeyomi Lawal</dc:creator>
      <pubDate>Wed, 29 Oct 2025 13:38:20 +0000</pubDate>
      <link>https://dev.to/adeyomi_lawal_8c61225e087/building-a-cross-platform-cli-tool-with-typescript-3f69</link>
      <guid>https://dev.to/adeyomi_lawal_8c61225e087/building-a-cross-platform-cli-tool-with-typescript-3f69</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every developer has seen this error:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;&lt;br&gt;
Error: Port 3000 is already in use&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And every developer has done this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Google&lt;/li&gt;
&lt;li&gt;Search "how to kill port process [your OS]"&lt;/li&gt;
&lt;li&gt;Copy-paste: &lt;code&gt;lsof -ti :3000 | xargs kill -9&lt;/code&gt; (macOS)&lt;/li&gt;
&lt;li&gt;Hope it works&lt;/li&gt;
&lt;li&gt;Repeat tomorrow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After doing this 100+ times, I decided to build a solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introducing zkill&lt;/strong&gt;&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%2Fkz0dsr5wy6gpfged5mor.png" 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%2Fkz0dsr5wy6gpfged5mor.png" alt=" " width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;zkill&lt;/code&gt; is a cross-platform CLI tool that kills zombie processes in one command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
zkill 3000&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it. Works on Mac, Linux, and Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🎯 &lt;strong&gt;Smart detection&lt;/strong&gt; - Shows what process is using the port&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Safe mode&lt;/strong&gt; - Asks for confirmation before killing&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Project-aware&lt;/strong&gt; - Remembers which ports belong to which projects&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Fast&lt;/strong&gt; - Less than 100ms to detect processes&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Beautiful CLI&lt;/strong&gt; - Color-coded output with spinners&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm install -g zombie-port-killer&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;`bash&lt;/p&gt;

&lt;h2&gt;
  
  
  Kill process on port 3000
&lt;/h2&gt;

&lt;p&gt;zkill 3000&lt;/p&gt;

&lt;h2&gt;
  
  
  Kill without confirmation
&lt;/h2&gt;

&lt;p&gt;zkill 3000 --force&lt;/p&gt;

&lt;h2&gt;
  
  
  List all active ports
&lt;/h2&gt;

&lt;p&gt;zkill scan&lt;/p&gt;

&lt;h2&gt;
  
  
  Show system info
&lt;/h2&gt;

&lt;p&gt;zkill info&lt;br&gt;
`&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Technical Deep Dive
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;I built zkill using a cross-platform adapter pattern. Each OS has its own adapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS&lt;/strong&gt;: Uses &lt;code&gt;lsof&lt;/code&gt; and &lt;code&gt;ps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux&lt;/strong&gt;: Uses &lt;code&gt;ss&lt;/code&gt; (or &lt;code&gt;netstat&lt;/code&gt; fallback) and &lt;code&gt;ps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: Uses &lt;code&gt;netstat&lt;/code&gt; and &lt;code&gt;tasklist&lt;/code&gt;/&lt;code&gt;taskkill&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[Code snippet of adapter pattern]&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript Setup
&lt;/h2&gt;

&lt;p&gt;Built entirely in TypeScript for type safety and better DX:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;json&lt;br&gt;
{&lt;br&gt;
  "compilerOptions": {&lt;br&gt;
    "target": "ES2020",&lt;br&gt;
    "module": "commonjs",&lt;br&gt;
    "strict": true,&lt;br&gt;
    // ...&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;114 tests covering all major functionality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit tests for services&lt;/li&gt;
&lt;li&gt;Integration tests for commands&lt;/li&gt;
&lt;li&gt;Cross-platform compatibility tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm test&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What I Learned
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Cross-Platform is Hard
&lt;/h2&gt;

&lt;p&gt;Different operating systems use completely different commands for process management. Windows was particularly challenging.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. UX Matters in CLI Tools
&lt;/h2&gt;

&lt;p&gt;Even in a terminal, UX matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Color-coded output&lt;/li&gt;
&lt;li&gt;Loading spinners&lt;/li&gt;
&lt;li&gt;Clear error messages&lt;/li&gt;
&lt;li&gt;Helpful prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Testing Saves Time
&lt;/h2&gt;

&lt;p&gt;Comprehensive tests caught platform-specific bugs early and gave me confidence to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Documentation is Critical
&lt;/h2&gt;

&lt;p&gt;A good README is the difference between 0 users and 1000 users.&lt;/p&gt;

&lt;h1&gt;
  
  
  Roadmap
&lt;/h1&gt;

&lt;p&gt;Coming in v1.1:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kill multiple ports: &lt;code&gt;zkill 3000 8000 5432&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Kill by process name: &lt;code&gt;zkill --name node&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Port range support: &lt;code&gt;zkill --range 3000-3010&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Try it Out!
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm install -g zombie-port-killer&lt;br&gt;
zkill --help&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;a href="https://www.npmjs.com/package/zombie-port-killer" rel="noopener noreferrer"&gt;npm package&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/adeyomilawal/zombie-port-killer" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐛 &lt;a href="https://github.com/adeyomilawal/zombie-port-killer/issues" rel="noopener noreferrer"&gt;Issues/Feedback&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zkill.dev" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What do you think? What features would you like to see next?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this useful, please star the repo and share it with other developers!&lt;/em&gt;&lt;br&gt;
&lt;code&gt;\&lt;/code&gt;`&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
