Common Clap patterns and idioms for argument parsing, validation, and CLI design. Use when implementing CLI arguments with Clap v4+.
View on GitHubgeoffjay/claude-plugins
rust-cli-developer
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/geoffjay/claude-plugins/blob/main/plugins/rust-cli-developer/skills/clap-patterns/SKILL.md -a claude-code --skill clap-patternsInstallation paths:
.claude/skills/clap-patterns/# Clap Patterns Skill
Common patterns and idioms for using Clap v4+ effectively in Rust CLI applications.
## Derive API vs Builder API
### When to Use Derive API
- CLI structure known at compile time
- Want type safety and compile-time validation
- Prefer declarative style
- Standard CLI patterns are sufficient
```rust
#[derive(Parser)]
#[command(version, about)]
struct Cli {
#[arg(short, long)]
input: PathBuf,
}
```
### When to Use Builder API
- CLI needs to be built dynamically at runtime
- Building plugin systems
- Arguments depend on configuration
- Need maximum flexibility
```rust
fn build_cli() -> Command {
Command::new("app")
.arg(Arg::new("input").short('i'))
}
```
## Common Patterns
### Global Options with Subcommands
```rust
#[derive(Parser)]
struct Cli {
#[arg(short, long, global = true, action = ArgAction::Count)]
verbose: u8,
#[command(subcommand)]
command: Commands,
}
```
### Argument Groups for Mutual Exclusivity
```rust
#[derive(Parser)]
#[command(group(
ArgGroup::new("format")
.required(true)
.args(&["json", "yaml", "toml"])
))]
struct Cli {
#[arg(long)]
json: bool,
#[arg(long)]
yaml: bool,
#[arg(long)]
toml: bool,
}
```
### Custom Value Parsers
```rust
fn parse_port(s: &str) -> Result<u16, String> {
let port: u16 = s.parse()
.map_err(|_| format!("`{s}` isn't a valid port"))?;
if (1024..=65535).contains(&port) {
Ok(port)
} else {
Err(format!("port not in range 1024-65535"))
}
}
#[derive(Parser)]
struct Cli {
#[arg(long, value_parser = parse_port)]
port: u16,
}
```
### Environment Variable Fallbacks
```rust
#[derive(Parser)]
struct Cli {
#[arg(long, env = "API_TOKEN")]
token: String,
#[arg(long, env = "API_ENDPOINT", default_value = "https://api.example.com")]
endpoint: String,
}
```
### Flattening Shared Options
```rust
#[derive(Args)]
struct CommonOpts {
#[arg(short, long)]
ver