<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Dipto's Blog]]></title><description><![CDATA[Dipto's Blog]]></description><link>https://blog.diptokarmakar.me</link><generator>RSS for Node</generator><lastBuildDate>Wed, 09 Sep 2026 18:31:48 GMT</lastBuildDate><atom:link href="https://blog.diptokarmakar.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I'm a Frontend Engineer Who'd Never Touched Go. I Shipped a Real Go CLI Tool Anyway — Here's What That Actually Looked Like]]></title><description><![CDATA[Every time Node.js ships a new LTS or Current release, upgrading means the same five manual steps: look up the new version, install it through whatever version manager you use, snapshot your global np]]></description><link>https://blog.diptokarmakar.me/built-nodeup-cli-tool-using-go-pair-programming-with-ai</link><guid isPermaLink="true">https://blog.diptokarmakar.me/built-nodeup-cli-tool-using-go-pair-programming-with-ai</guid><category><![CDATA[cli tool]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Dipto Karmakar]]></dc:creator><pubDate>Wed, 08 Jul 2026 20:31:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/5773ae3f7e3e843348ce42e0/31588dfa-42d4-44fc-a9ec-58efefa1cbdc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every time Node.js ships a new LTS or Current release, upgrading means the same five manual steps: look up the new version, install it through whatever version manager you use, snapshot your global npm packages, reinstall them on the new version, and clean up the old one. I got tired of doing this by hand, so I built nodeup — a CLI that collapses all of it into one command: nodeup upgrade.</p>
<p>Here's the part that's more interesting than the tool itself: I'm a Senior Frontend Engineer. React, TypeScript, Next.js — that's my whole career. I had never written a line of Go before this project. I built it anyway, using AI tools heavily to learn the language and write the code, because a tool that manages your Node installs can't depend on Node itself to run.</p>
<h2>What "AI-assisted" actually meant day to day</h2>
<p>It didn't mean typing "build me a Node version manager" and shipping whatever came out. It meant constantly making calls an AI can't make for you: how should the package boundaries in internal/ be drawn so the CLI layer doesn't leak into the detection logic? Which of the eight version managers (fnm, nvm, Volta, asdf, mise, n, nodenv, nvm-windows) actually needed special-casing, and which could share a common interface? When the AI suggested something that compiled fine but wasn't idiomatic Go, how would I even know, since I didn't have the instinct for what "idiomatic" looks like yet?</p>
<p>That last one is the real answer to "isn't this just vibe coding": the AI can write plausible-looking Go all day. It can't tell you whether the plausible-looking Go is actually good, and neither could I, at first. I closed that gap by asking it to explain why a pattern was idiomatic, not just apply it, and by leaning hard on golangci-lint with staticcheck, gocritic, and errcheck enabled — tools that catch a lot of what a human reviewer would catch, even when the human reviewer (me) didn't know Go well enough to catch it themselves.</p>
<h2>Treating it like a real release, not a script</h2>
<p>The part I'm genuinely proud of isn't the Go code — it's what surrounds it. Full CI across 5 platform builds (linux/darwin × amd64/arm64, windows/amd64), tests running on Ubuntu, macOS, and Windows separately, Conventional Commits enforced by commitlint, and a GoReleaser pipeline where a single git tag pushes a release to a Homebrew tap, a Scoop bucket, and npm (via OIDC trusted publishing) simultaneously. None of that happens by accepting AI suggestions — it's the kind of infrastructure decision-making that's identical whether you're writing Go, TypeScript, or anything else, and it's arguably the more transferable skill here.</p>
<h2><strong>Where it's honestly still weak</strong></h2>
<p>I use fnm + Homebrew on macOS daily, so that path is well-tested. nvm-windows, asdf, and mise have had far less real-world exercise than I'd like before calling this fully solid — if you're on one of those and something breaks, I'd genuinely appreciate a bug report over at the repo (<a href="https://github.com/dipto0321/nodeup">nodeup</a>).</p>
<h2>Why write this up</h2>
<p>Partly because I think the discourse around AI-assisted code is stuck between "it's all slop" and "just ship it," and neither matches what building this actually involved. And partly because I don't know many people who've documented a first systems-language project done this way — there's a whole companion guide in the repo (LEARN_GO_AND_NODEUP.md) teaching Go through the actual codebase, for anyone starting from exactly where I did.</p>
<p>If you're a Node developer, I'd love for you to try nodeup. If you're a Go developer, I'd love your honest opinion on where the seams show.</p>
<p>One more thing: I'm currently open to senior frontend/full-stack remote roles. If the way I approach shipping something end-to-end, outside my comfort zone, is useful to your team — I'd love to talk.</p>
]]></content:encoded></item></channel></rss>