cli-patterns
Lightweight Go CLI patterns using urfave/cli. Use when building CLI tools, creating commands with flags, implementing subcommands, adding before/after hooks, organizing command categories, or when user mentions Go CLI, urfave/cli, cobra alternatives, CLI flags, CLI categories.
When & Why to Use This Skill
This Claude skill provides a comprehensive suite of lightweight Go CLI patterns and templates powered by the urfave/cli framework. It is designed to accelerate the development of production-ready command-line applications by offering battle-tested structures for subcommands, advanced flag management, lifecycle hooks, and automated scaffolding scripts. By focusing on simplicity and performance, it helps developers build maintainable tools that follow industry best practices for CLI design.
Use Cases
- Rapidly scaffolding new Go-based command-line utilities using pre-defined templates and generation scripts.
- Implementing complex multi-level command hierarchies and organized command categories for professional-grade CLI tools.
- Managing application state and configuration through robust flag systems, environment variable fallbacks, and context sharing.
- Migrating existing CLI projects from heavier frameworks like Cobra to a more lightweight, faster-compiling alternative.
- Adding lifecycle management to tools using Before/After hooks for database connections, authentication, or resource cleanup.
| name | cli-patterns |
|---|---|
| description | Lightweight Go CLI patterns using urfave/cli. Use when building CLI tools, creating commands with flags, implementing subcommands, adding before/after hooks, organizing command categories, or when user mentions Go CLI, urfave/cli, cobra alternatives, CLI flags, CLI categories. |
| allowed-tools | Bash, Read, Write, Edit |
CLI Patterns Skill
Lightweight Go CLI patterns using urfave/cli for fast, simple command-line applications.
Overview
Provides battle-tested patterns for building production-ready CLI tools in Go using urfave/cli v2. Focus on simplicity, speed, and maintainability over complex frameworks like Cobra.
Why urfave/cli?
- Lightweight: Minimal dependencies, small binary size
- Fast: Quick compilation, fast execution
- Simple API: Easy to learn, less boilerplate than Cobra
- Production-ready: Used by Docker, Nomad, and many other tools
- Native Go: Feels like standard library code
Core Patterns
1. Basic CLI Structure
Use templates/basic-cli.go for simple single-command CLIs:
- Main command with flags
- Help text generation
- Error handling
- Exit codes
2. Subcommands
Use templates/subcommands-cli.go for multi-command CLIs:
- Command hierarchy (app → command → subcommand)
- Shared flags across commands
- Command aliases
- Command categories
3. Flags and Options
Use templates/flags-demo.go for comprehensive flag examples:
- String, int, bool, duration flags
- Required vs optional flags
- Default values
- Environment variable fallbacks
- Flag aliases (short and long forms)
- Custom flag types
4. Command Categories
Use templates/categories-cli.go for organized command groups:
- Group related commands
- Better help text organization
- Professional CLI UX
- Examples: database commands, deploy commands, etc.
5. Before/After Hooks
Use templates/hooks-cli.go for lifecycle management:
- Global setup (before all commands)
- Global cleanup (after all commands)
- Per-command setup/teardown
- Initialization and validation
- Resource management
6. Context and State
Use templates/context-cli.go for shared state:
- Pass configuration between commands
- Share database connections
- Manage API clients
- Context values
Scripts
Generation Scripts
scripts/generate-basic.sh <app-name>
- Generates basic CLI structure
- Creates main.go with single command
- Adds common flags (verbose, config)
- Includes help text template
scripts/generate-subcommands.sh <app-name>
- Generates multi-command CLI
- Creates command structure
- Adds subcommand examples
- Includes command categories
scripts/generate-full.sh <app-name>
- Generates complete CLI with all patterns
- Includes before/after hooks
- Adds comprehensive flag examples
- Sets up command categories
- Includes context management
Utility Scripts
scripts/add-command.sh <app-name> <command-name>
- Adds new command to existing CLI
- Updates command registration
- Creates command file
- Adds to appropriate category
scripts/add-flag.sh <file> <flag-name> <flag-type>
- Adds flag to command
- Supports all flag types
- Includes environment variable fallback
- Adds help text
scripts/validate-cli.sh <project-path>
- Validates CLI structure
- Checks for common mistakes
- Verifies flag definitions
- Ensures help text exists
Templates
Core Templates
templates/basic-cli.go
- Single-command CLI
- Standard flags (verbose, version)
- Error handling patterns
- Exit code management
templates/subcommands-cli.go
- Multi-command structure
- Command registration
- Shared flags
- Help text organization
templates/flags-demo.go
- All flag types demonstrated
- Environment variable fallbacks
- Required flag validation
- Custom flag types
templates/categories-cli.go
- Command categorization
- Professional help output
- Grouped commands
- Category-based organization
templates/hooks-cli.go
- Before/After hooks
- Global setup/teardown
- Per-command hooks
- Resource initialization
templates/context-cli.go
- Context management
- Shared state
- Configuration passing
- API client sharing
TypeScript Equivalent (Node.js)
templates/commander-basic.ts
- commander.js equivalent patterns
- TypeScript type safety
- Similar API to urfave/cli
templates/oclif-basic.ts
- oclif framework patterns (Heroku/Salesforce style)
- Class-based commands
- Plugin system
Python Equivalent
templates/click-basic.py
- click framework patterns
- Decorator-based commands
- Python CLI best practices
templates/typer-basic.py
- typer framework (FastAPI CLI)
- Type hints for validation
- Modern Python patterns
Examples
Example 1: Database CLI Tool
examples/db-cli/
- Complete database management CLI
- Commands: connect, migrate, seed, backup
- Categories: schema, data, admin
- Before hook: validate connection
- After hook: close connections
Example 2: Deployment Tool
examples/deploy-cli/
- Deployment automation CLI
- Commands: build, test, deploy, rollback
- Categories: build, deploy, monitor
- Context: share deployment config
- Hooks: setup AWS credentials
Example 3: API Client
examples/api-cli/
- REST API client CLI
- Commands: get, post, put, delete
- Global flags: auth token, base URL
- Before hook: authenticate
- Context: share HTTP client
Example 4: File Processor
examples/file-cli/
- File processing tool
- Commands: convert, validate, optimize
- Categories: input, output, processing
- Flags: input format, output format
- Progress indicators
Best Practices
CLI Design
- Keep it simple: Start with basic structure, add complexity as needed
- Consistent naming: Use kebab-case for commands (deploy-app, not deployApp)
- Clear help text: Every command and flag needs description
- Exit codes: Use standard codes (0=success, 1=error, 2=usage error)
Flag Patterns
- Environment variables: Always provide env var fallback for important flags
- Sensible defaults: Required flags should be rare
- Short and long forms: -v/--verbose, -c/--config
- Validation: Validate flags in Before hook, not in action
Command Organization
- Categories: Group related commands (>5 commands = use categories)
- Aliases: Provide shortcuts for common commands
- Subcommands: Use for hierarchical operations (db migrate up/down)
- Help text: Keep concise, provide examples
Performance
- Fast compilation: urfave/cli compiles faster than Cobra
- Small binaries: Minimal dependencies = smaller output
- Startup time: Use Before hooks for expensive initialization
- Lazy loading: Don't initialize resources unless command needs them
Common Patterns
Configuration File Loading
app.Before = func(c *cli.Context) error {
configPath := c.String("config")
if configPath != "" {
return loadConfig(configPath)
}
return nil
}
Environment Variable Fallbacks
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
Usage: "API token",
EnvVars: []string{"API_TOKEN"},
}
Required Flags
&cli.StringFlag{
Name: "host",
Required: true,
Usage: "Database host",
}
Global State Management
type AppContext struct {
Config *Config
DB *sql.DB
}
app.Before = func(c *cli.Context) error {
ctx := &AppContext{
Config: loadConfig(),
}
c.App.Metadata["ctx"] = ctx
return nil
}
Validation
Run scripts/validate-cli.sh to check:
- All commands have descriptions
- All flags have usage text
- Before/After hooks are properly defined
- Help text is clear and concise
- No unused imports
- Proper error handling
Migration Guides
From Cobra to urfave/cli
See examples/cobra-migration/ for:
- Command mapping (cobra.Command → cli.Command)
- Flag conversion (cobra flags → cli flags)
- Hook equivalents (PreRun → Before)
- Context differences
From Click (Python) to urfave/cli
See examples/click-migration/ for:
- Decorator to struct conversion
- Option to flag mapping
- Context passing patterns
References
- urfave/cli v2 Documentation
- Docker CLI Source - Real-world example
- Go CLI Best Practices