Skip to main content

Command Palette

Search for a command to run...

Your First CLI in Go

Updated
•4 min read•View as Markdown
Your First CLI in Go
O

Hi, I’m Oluwatosin Thompson, a Backend Engineer specialising in Go (Golang) and passionate about creating reliable, scalable, and efficient backend systems that power great products.

I’ve built and maintained production-grade services using Temporal, Prometheus, and AWS, with a strong emphasis on performance optimisation, distributed systems, and clean, maintainable code. My work reflects a balance between technical excellence and real-world business impact.

I enjoy sharing my learning journey through technical writing and documenting how I solve engineering challenges. Known for being teachable, adaptable, and detail-oriented, I’m always eager to take on complex problems and deliver elegant solutions.

I’m committed to engineering growth, collaboration, and continuous improvement, with a long-term goal of building impactful systems used worldwide.

What is a CLI?

A CLI stands for Command Line Interface. It is a program you talk to by typing in a terminal, not by clicking buttons on a screen.

You have probably used CLIs before. When you type cd Documents, ls, git status, etc, you are talking to a CLI.

An image of a Command Line Interface

These are programs that take your words (called arguments) and do something with them. Today, we are going to build one!


What We are Building

We are going to build a small Go program called greeter. You can run it in the terminal like this:

go run main.go thegoninja

And it prints:

Hello, thegoninja!

That is it. Simple, clean, and a great starting point for building great CLIs.


Setting Up

Search for the terminal on your computer and open it. There, create a new folder and a file called main.go inside it. To do this, type the following one after the other and hit enter after each one.

mkdir greeter
cd greeter
touch main.go

Proceed to locate and open main.go in your editor and add this:

package main

import "fmt"

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

Run it in your terminal:

go run main.go

You should see:

Hello, World!

Good! Our Go program is working. Now let us make it read your name from the terminal.


Reading Arguments with os.Args

When you run a Go program, everything you type after go run main.go is captured in a special slice called os.Args.

Let's think of a slice like a numbered list. Each word you type gets a spot in the list.

Index Value
0 main.go
1 thegoninja

The first item (index 0) is always the name of the program being run itself. Your actual argument starts from index 1.

Now let's update our main.go to read the name from the CLI:

package main

import (
    "fmt"
    "os"
)

func main() {
    name := os.Args[1]
    fmt.Println("Hello, " + name + "!")
}

Back to the terminal; run it:

go run main.go thegoninja

Output:

Hello, the goninja

It works. We have just built a CLI that accepts input.


What If We Forget to Pass a Name?

Let's try running with no name:

go run main.go

A CRASH 💥

panic: runtime error: index out of range [1] with length 1

This is Go telling us: "You tried to grab index 1 from the list within your main.go but the list only has one item."

We need to avoid this. Let's update the code:

package main

import (
    "fmt"
    "os"
)

func main() {
    if len(os.Args) < 2 {
        fmt.Println("Usage: greeter <name>")
        return
    }

    name := os.Args[1]
    fmt.Println("Hello, " + name + "!")
}

Now run it with no name:

go run main.go
Usage: greeter <name>

Much better. We now know what to do instead of the program crashing outright.


Building It as a Real Binary

Right now, we are running the program with go run. That is fine for development, but a real CLI is a file you can run on its own.

Build it like this:

go build -o greeter main.go

Now run it directly:

./greeter John

Output:

Hello, John!

We now have a real binary. We could move this file anywhere on our computer, and it would still work.


What You Learned

  • A CLI is a program you control by typing in a terminal

  • Go stores your terminal input in os.Args

  • os.Args[0] is always the program name. Your input starts at os.Args[1]

  • Always check len(os.Args) before accessing arguments, so your program does not crash

  • Use go build to turn your program into a standalone binary


What Is Next

In the next article, we level up. Instead of passing a plain name, you will use flags like:

--name John and --greeting Hi

You will learn Go's flag package and understand the difference between arguments and flags.


References

CLI in Go: From Zero to Binary

Part 2 of 2

You do not need to know everything about Go to build real tools. This series takes you from your very first terminal program all the way to a full CLI app, one small step at a time. No jargon, no skipping steps, just code that works.

Start from the beginning

Flags and Options in Go CLIs

Quick Recap In Article 1, we built a small Go CLI that reads a name from the terminal using os.Args. We ran it like this: ./greeter John And printed: Hello, John! That works, but it has a problem. W