Skip to content
/ gum Public

A blazingly fast, elegant, and dependency-free library for building command-line interfaces in Go.

License

Notifications You must be signed in to change notification settings

zyedev/gum

Repository files navigation


  ███████╗ ██╗   ██╗███╗   ███╗
  ██╔════╝ ██║   ██║████╗ ████║
  ███████╗ ██║   ██║██╔████╔██║
  ██═══██║ ██║   ██║██║╚██╔╝██║
  ███████║ ╚██████╔╝██║ ╚═╝ ██║
  ╚══════╝  ╚═════╝ ╚═╝     ╚═╝
  

A blazingly fast, elegant, and dependency-free library for building command-line interfaces in Go.


Go Reference License Dependencies

gum provides a powerful, fluent API that makes defining complex command-line applications simple and readable. It is built from the ground up with performance and developer experience as first-class citizens.

✨ Why Gum?

  • Fluent, Chainable API: Structure your CLI in a natural, declarative way.
  • Zero Dependencies: Keep your applications light and your builds fast. No external modules needed.
  • Blazingly Fast: Optimized for minimal memory allocations and high performance. See the benchmarks below.
  • Automatic Help Generation: Beautiful, detailed, and context-aware help text for all commands.
  • Built-in Shell Completion: Add Bash and Zsh completion with a single line of code.
  • Powerful Middleware: Use UnsureAction to create logging, metrics, or validation layers that don't halt execution.
  • Robust & Battle-Tested: A comprehensive test suite ensures reliability.

🚀 Performance

gum is designed to be exceptionally fast. Benchmarks run on a standard Intel(R) Core(TM) i5-5200U show just how little overhead the library adds.

Benchmark Task Time / Operation Memory / Operation Allocations / Operation
Simple Parse ~2,565 ns/op 864 B/op 11 allocs/op
Complex Parse ~2,644 ns/op 1088 B/op 10 allocs/op
Help Text Generation ~10,529 ns/op 2984 B/op 59 allocs/op

This means gum can parse even complex commands with subcommands and multiple flags in ~2.6 microseconds while allocating just over 1KB of memory.

📦 Getting Started

First, add gum to your project:

go get github.com/devmdo/gum

Next, create a simple main.go file. This example demonstrates a root command with a flag and a subcommand in just a few lines.

// main.go
package main

import (
	"fmt"

	"github.com/devmdo/gum"
)

func main() {
	app := gum.NewApp("git").
		Description("A simple git-like example app").
		Version("1.0.0").
		Option("-v, --verbose", "Enable verbose output") // Global flag

	// Define the 'clone' command
	app.Command("clone, c").
		Description("Clone a repository into a new directory").
		Arg("repository", "The repository to clone").
		Option("-b, --branch", "Branch to checkout", "main").
		Action(func(args *gum.Args) error {
			repo := args.Arg(0)
			branch := args.String("branch")

			fmt.Printf("Cloning repository '%s' on branch '%s'...\n", repo, branch)
			if args.Bool("verbose") {
				fmt.Println("Verbose mode enabled.")
			}
			return nil
		})

	// Run the application
	app.Run()
}

Try it out!

# Build the application
go build .

# Run the subcommand
./git clone https://github.com/my/repo
# Output: Cloning repository 'https://github.com/my/repo' on branch 'main'...

# Use aliases, flags, and global flags
./git -v c https://github.com/my/repo --branch dev
# Output: Cloning repository 'https://github.com/my/repo' on branch 'dev'...
#         Verbose mode enabled.

# Get automatically generated help
./git clone --help

📖 Features in Detail

1. Commands, Subcommands, and Aliases

The core of gum is the Command. You can chain .Command() calls to create nested subcommands. Provide a comma-separated string to define a primary name and its aliases.

func main() {
	app := gum.NewApp("docker")

	// Command with aliases
	app.Command("run, r").
		Description("Run a command in a new container")

	// Nested subcommands
	remote := app.Command("remote").
		Description("Manage remote connections")

	remote.Command("add").
		Description("Add a new remote")

	remote.Command("rm, remove").
		Description("Remove a remote")
    
    app.Run()
}

2. Arguments and Options (Flags)

gum supports positional arguments and a rich set of flag types.

  • Positional Arguments: Use .Arg() to define arguments for documentation in the help text.
    app.Command("clone").
        Arg("repository", "The repository to clone").
        Arg("directory", "The destination directory (optional)")
  • Options (Flags): Use .Option() to define flags.
    // Boolean flag (present or not)
    app.Option("-v, --verbose", "Enable verbose output")
    
    // Flag that takes a value
    app.Option("-o, --output", "Specify output file")
    
    // Flag with a default value
    app.Option("--port", "The port to listen on", "8080")
  • Parsing Formats: gum handles all common formats automatically:
    • --flag value
    • --flag=value
    • -f value
    • -abc (for combined boolean flags)

3. Actions and Accessing Values

The .Action() method is where your command's logic lives. It receives an *Args object to access parsed values.

app.Command("commit").
    Option("-m, --message", "The commit message").
    Option("-a, --all", "Stage all changed files").
    Action(func(args *gum.Args) error {
        // BTW you can count args by args.Len()

        // Check for boolean flag
        if args.Bool("all") {
            fmt.Println("Staging all files...")
        }

        // Get string value from a flag (works with -m or --message)
        message := args.String("message")
        if message == "" {
            return errors.New("commit message is required")
        }

        // Get positional arguments by index
        // e.g., for a command `my-app get user 123`
        resource := args.Arg(0) // "user"
        idStr := args.Arg(1)    // "123"

        // Type conversion helpers
        id, err := args.Int("id") // Also supports Float64()
        if err != nil {
            return err
        }

        fmt.Printf("Committing with message: %s\n", message)
        return nil
    })

4. Automatic Help Text

gum generates beautiful and useful help text automatically. Simply run your command with --help or provide no action for a command that has subcommands.

You can customize the output with:

  • .Description(string): Set the main description.
  • .Example(string): Provide a specific usage example.
  • .ExtraUsage(string): Add a free-form text block at the end of the help message.

Example output for ./git clone --help:

A test CLI application.

USAGE:
  test-cli clone <repo> [options]

ARGUMENTS:
  repo   The repository URL.

OPTIONS:
  --branch, -b   The branch to checkout (default: "main")
  --config       Path to a custom config file (default: "default.json")
  -v             Enable verbose output
  -R             Recursive
  --version      Print version information and exit

EXAMPLE:
  test-cli clone my-repo --branch dev

5. Automatic Shell Completion

Provides a first-class user experience by adding shell completion for bash and zsh.

Your users can enable it with a simple command:

Bash:

eval "$(your-app completion bash)"
```**Zsh:**
```bash
eval "$(your-app completion zsh)"

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

A blazingly fast, elegant, and dependency-free library for building command-line interfaces in Go.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages