Skip to content
Barebones subcommand handling
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


GoDoc Go Report Card

go get

flagg is a tiny package that makes it easier to build CLI apps that use subcommands. I built it because the stdlib flag package is too low-level, but popular alternatives like spf13/cobra are full-fledged frameworks with too many bells and whistles for my liking. flagg is 67 lines of code and imports only stdlib packages.

flagg is designed around the stdlib *flag.FlagSet type. You represent each subcommand in your app with a *flag.FlagSet, and arrange them into a hierarchy with flagg.Tree. Then just call flagg.Parse to parse the subcommand selected by os.Args.


// commands are just *flag.FlagSets
var rootCmd *flag.FlagSet = flagg.Root
rootCmd.Usage = flagg.SimpleUsage(rootCmd, "An example program")
verbose := rootCmd.Bool("v", false, "display verbose output")

// flagg.New constructs a *flag.FlagSet with the given name and usage
// description
fooCmd := flagg.New("foo", "The foo subcommand")
bars := fooCmd.Int("bars", 0, "number of bars to foo")
quuxCmd := flagg.New("quux", "The quux subcommand")

// construct the command hierarchy
tree := flagg.Tree{
	Cmd: rootCmd,
	Sub: []flagg.Tree{
		{Cmd: fooCmd},
		{Cmd: quuxCmd},

// Parse the command hierarchy. cmd is the selected command, e.g. if
// os.Args = []string{"./example", "quux"}, then cmd == quuxCmd.
cmd := flagg.Parse(tree)

// again, cmd is just a *flag.FlagSet, so Args() returns the arguments of the
// selected command.
args := cmd.Args()

// use a switch to identify the cmd that was selected
switch cmd {
case fooCmd:
	fmt.Printf("fooing %v bars\n", *bars)
case quuxCmd:
	fmt.Println("quux!", args)
You can’t perform that action at this time.