Go Lesson 46 – CLI Apps | Dataplexa

Building CLI Apps with Go

Command-line applications (CLI tools) are one of Go’s strongest use cases. Many popular developer tools are written in Go because of its speed, simple deployment, and clean syntax.

In this lesson, you will learn how to build real CLI applications in Go, handle user input, flags, arguments, and structure production-ready tools.


What Is a CLI Application?

A CLI application is a program that runs in a terminal and accepts commands, options, and arguments instead of using a graphical interface.

Examples include git, docker, kubectl, and go itself.


Basic CLI Program

A basic Go CLI program starts with the main function.

package main

import "fmt"

func main() {
    fmt.Println("Hello from Go CLI")
}

Run it using:

go run main.go

Reading Command-Line Arguments

Go provides access to CLI arguments using the os package.

package main

import (
    "fmt"
    "os"
)

func main() {
    args := os.Args
    fmt.Println("Arguments:", args)
}

If you run:

go run main.go build prod

You will receive:

[main.go build prod]

Ignoring the Program Name

The first argument is always the program name. Most CLI tools ignore it.

args := os.Args[1:]
fmt.Println("User arguments:", args)

Building a Simple Calculator CLI

Let’s build a real CLI tool that adds numbers.

package main

import (
    "fmt"
    "os"
    "strconv"
)

func main() {
    if len(os.Args) < 3 {
        fmt.Println("Usage: add num1 num2")
        return
    }

    a, _ := strconv.Atoi(os.Args[1])
    b, _ := strconv.Atoi(os.Args[2])

    fmt.Println("Sum:", a+b)
}

Using the flag Package

For professional CLI apps, Go provides the flag package.

package main

import (
    "flag"
    "fmt"
)

func main() {
    name := flag.String("name", "User", "Your name")
    age := flag.Int("age", 0, "Your age")

    flag.Parse()

    fmt.Println("Name:", *name)
    fmt.Println("Age:", *age)
}

Run it like:

go run main.go -name Alice -age 30

Handling Subcommands

Many CLI tools use subcommands like:

app create
app delete
app list

You can implement this using argument checks.

switch os.Args[1] {
case "create":
    fmt.Println("Creating item")
case "delete":
    fmt.Println("Deleting item")
default:
    fmt.Println("Unknown command")
}

Structuring a CLI Project

A clean CLI project structure looks like:

mycli/
 ├── main.go
 ├── cmd/
 │   ├── create.go
 │   └── delete.go
 └── internal/

This structure scales well for large tools.


Building a Binary

One of Go’s biggest strengths is producing a single executable file.

go build -o mycli

You can now run:

./mycli

Cross-Platform Builds

Go supports cross-compilation.

GOOS=windows GOARCH=amd64 go build -o mycli.exe

Best Practices for CLI Apps

  • Provide clear help messages
  • Validate user input
  • Return meaningful exit codes
  • Keep commands small and focused
  • Log errors properly

Practice Exercises

Exercise 1

Create a CLI tool that prints the square of a number.

Exercise 2

Add a -version flag that prints app version.


Key Takeaways

  • Go is ideal for CLI tools
  • os.Args handles raw arguments
  • flag simplifies option parsing
  • Go builds fast, portable binaries

What’s Next?

In the next lesson, you will learn how to test Go applications using Go’s built-in testing framework.