← All posts

Why I Rewrote My Side Project in Go

After months of maintaining a Node.js CLI tool, I decided to rewrite it in Go. Here's why that decision made sense and what I learned along the way.

The Problem with Node.js for CLI Tools

Don't get me wrong — Node.js is fantastic for many things. But for CLI tools that need to be distributed as standalone binaries, it presents some challenges:

  • Distribution complexity: Users need Node.js installed, or you need to bundle the entire runtime
  • Startup time: Cold starts can be slow, especially with many dependencies
  • Binary size: Bundled executables can be massive

Why Go?

Go addresses these issues elegantly:

package main

import "fmt"

func main() {
    fmt.Println("Hello, CLI!")
}

This compiles to a single, static binary that runs anywhere. No runtime required.

Key Benefits

  1. Fast compilation — The Go compiler is incredibly quick
  2. Cross-compilation — Build for any platform from any platform
  3. Excellent standard library — Most things you need are built-in
  4. Concurrency primitives — Goroutines make parallel operations simple

The Migration Process

I approached the rewrite incrementally:

  1. Started with the core data structures
  2. Ported the command-line argument parsing (using Cobra)
  3. Migrated file system operations
  4. Added tests for each component

Results

After the rewrite:

  • Binary size: 8MB (down from 45MB bundled)
  • Startup time: ~10ms (down from ~500ms)
  • No external dependencies for users

Conclusion

Go isn't the right choice for every project, but for CLI tools, it's hard to beat. The combination of easy distribution, excellent performance, and a great developer experience makes it my go-to for this type of work.