Skip to content

CLI best practices

Well‑designed CLI tools follow common conventions: help text, exit codes, output formatting, and error handling.

  • Help text – Provide -h or --help with clear usage.
  • Exit codes0 for success, non‑zero for errors.
  • Output – Use fmt.Println for normal output, fmt.Fprintln(os.Stderr, ...) for errors.
  • Silence – Allow quiet mode (-q).
  • Progress – Use progress bars for long operations (e.g., github.com/schollz/progressbar).
  • Colour – Use colour for readability, but respect NO_COLOR environment variable.
  • Subcommands – Group related actions (like git add, git commit).
  • Configuration – Support flags, environment variables, and config files (use Viper).

A well‑structured CLI with proper exit codes.

package main
import (
"flag"
"fmt"
"os"
)
func main() {
name := flag.String("name", "", "your name")
flag.Parse()
if *name == "" {
fmt.Fprintln(os.Stderr, "error: --name is required")
os.Exit(1)
}
fmt.Printf("Hello, %s\n", *name)
os.Exit(0)
}
Terminal window
error: --name is required