Building a CLI Tool in Go from Scratch

Go has become the default language for CLI tools for a good reason: it compiles to a single static binary with no runtime dependencies, cross-compiles trivially to any OS/architecture, and starts instantly. Docker, Kubernetes, and Terraform are all written in it partly for exactly this reason.

A Minimal CLI with Cobra

go mod init github.com/you/wordcount
go get github.com/spf13/cobra@latest
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"

    "github.com/spf13/cobra"
)

func main() {
    var rootCmd = &cobra.Command{
        Use:   "wordcount [file]",
        Short: "Count words in a text file",
        Args:  cobra.ExactArgs(1),
        Run: func(cmd *cobra.Command, args []string) {
            file, err := os.Open(args[0])
            if err != nil {
                fmt.Println("Error:", err)
                os.Exit(1)
            }
            defer file.Close()

            count := 0
            scanner := bufio.NewScanner(file)
            scanner.Split(bufio.ScanWords)
            for scanner.Scan() {
                count++
            }
            fmt.Printf("%d words in %s\n", count, args[0])
        },
    }
    rootCmd.Execute()
}

Cross-Compiling for Every Platform

GOOS=linux   GOARCH=amd64 go build -o wordcount-linux-amd64
GOOS=darwin  GOARCH=arm64 go build -o wordcount-macos-arm64
GOOS=windows GOARCH=amd64 go build -o wordcount-windows.exe

Why This Beats Python for Distribution

A Python CLI tool requires the end user to have the right Python version and dependencies installed — genuinely painful to distribute to non-developers. A Go binary is a single file: download it, run it, done. That difference alone explains why so much modern infrastructure tooling standardized on Go.