Skip to main content

Command Palette

Search for a command to run...

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

Updated
4 min readView as Markdown
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
D
I'm a Senior Frontend Engineer with 10+ years of experience building modern web applications using React, TypeScript, and Next.js. I've worked remotely with startups and product teams across Europe and North America, designing scalable frontend architectures, reusable component systems, and high-performance user experiences. I enjoy solving complex engineering problems, improving developer workflows, contributing to open source, and sharing practical lessons from real-world software development.

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.

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.

What "AI-assisted" actually meant day to day

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?

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.

Treating it like a real release, not a script

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.

Where it's honestly still weak

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 (nodeup).

Why write this up

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.

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.

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.