Build production CLI tools with Cobra, Viper, and terminal UI
View on GitHubpluginagentmarketplace/custom-plugin-go
go-development-assistant
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/pluginagentmarketplace/custom-plugin-go/blob/main/skills/go-cli-tools/SKILL.md -a claude-code --skill go-cli-toolsInstallation paths:
.claude/skills/go-cli-tools/# Go CLI Tools Skill
Build professional command-line applications with Go.
## Overview
Complete guide for building CLI tools with Cobra, Viper configuration, terminal UI, and cross-platform support.
## Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| framework | string | no | "cobra" | CLI framework |
| config_format | string | no | "yaml" | Config: "yaml", "json", "toml" |
| interactive | bool | no | false | Include interactive prompts |
## Core Topics
### Cobra Setup
```go
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "My CLI application",
Version: version,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return initConfig()
},
}
func Execute() int {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
return 0
}
func init() {
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
}
```
### Subcommands
```go
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start the server",
RunE: func(cmd *cobra.Command, args []string) error {
port, _ := cmd.Flags().GetInt("port")
return runServer(port)
},
}
func init() {
serveCmd.Flags().IntP("port", "p", 8080, "server port")
rootCmd.AddCommand(serveCmd)
}
```
### Viper Configuration
```go
func initConfig() error {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
home, _ := os.UserHomeDir()
viper.AddConfigPath(home)
viper.AddConfigPath(".")
viper.SetConfigName(".myapp")
viper.SetConfigType("yaml")
}
viper.SetEnvPrefix("MYAPP")
viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigF