TL;DR:
clap(Command Line Argument Parser) is the standard way to parseargvin Rust. The derive API lets you define your CLI as a struct with#[derive(Parser)]; clap generates the parser, help text, and validation automatically. You get subcommands, typed arguments, default values, environment variable fallbacks, and shell completion generation out of the box.
How Do You Use clap With the Derive API?
Annotate a struct with #[derive(Parser)]; clap reads the struct fields and doc comments to build the full CLI automatically.
[dependencies]
clap = { version = "4", features = ["derive"] }use clap::Parser;
/// A fast file search tool
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// Pattern to search for
pattern: String,
/// File to search in
path: std::path::PathBuf,
/// Show line numbers
#[arg(short, long)]
line_numbers: bool,
/// Max results to show (default: 100)
#[arg(short, long, default_value_t = 100)]
max_results: usize,
}
fn main() {
let args = Args::parse();
println!("Searching for '{}' in {:?}", args.pattern, args.path);
}Running cargo run -- --help outputs:
A fast file search tool
Usage: myapp [OPTIONS] <PATTERN> <PATH>
Arguments:
<PATTERN> Pattern to search for
<PATH> File to search in
Options:
-l, --line-numbers Show line numbers
-m, --max-results <N> Max results to show [default: 100]
-h, --help Print help
-V, --version Print versionHow Do You Define Subcommands?
Use an enum with #[derive(Subcommand)]; each variant is a subcommand with its own arguments.
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(version, about)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Add a new item
Add {
/// Name of the item
name: String,
},
/// List all items
List {
/// Show only active items
#[arg(short, long)]
active: bool,
},
/// Remove an item by ID
Remove { id: u64 },
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::Add { name } => println!("Adding: {name}"),
Commands::List { active } => println!("Listing (active={active})"),
Commands::Remove { id } => println!("Removing: {id}"),
}
}How Do You Read From Environment Variables?
Use #[arg(env = "VAR_NAME")] to fall back to an environment variable if the flag isn't provided.
use clap::Parser;
#[derive(Parser)]
struct Config {
/// Database URL (or DATABASE_URL env var)
#[arg(long, env = "DATABASE_URL")]
database_url: String,
/// API key (or API_KEY env var)
#[arg(long, env = "API_KEY", hide_env_values = true)]
api_key: String,
}Priority: CLI flag > environment variable > default value. hide_env_values = true prevents the env value from showing in help output (important for secrets).
What Is the Builder API?
The builder API constructs the CLI programmatically with method chains; useful when the structure is dynamic or when you can't use derive.
use clap::{Arg, Command};
fn main() {
let matches = Command::new("myapp")
.version("1.0")
.arg(Arg::new("pattern").required(true))
.arg(
Arg::new("verbose")
.short('v')
.long("verbose")
.action(clap::ArgAction::SetTrue),
)
.get_matches();
let pattern = matches.get_one::<String>("pattern").unwrap();
let verbose = matches.get_flag("verbose");
}For most use cases, the derive API is clearer and more maintainable.
Frequently Asked Questions
structopt was the original derive-based wrapper around clap. As of clap v3+, the derive API is built directly into clap; structopt is now deprecated. Use clap with features = ["derive"].
Use #[arg(value_parser = ...)] with a custom function, or use clap's built-in value parsers for ranges and enums:
#[arg(value_parser = clap::value_parser!(u16).range(1..=65535))]
port: u16,Yes; use clap_complete crate to generate completion scripts for Bash, Zsh, Fish, PowerShell, and Elvish.
Positional arguments are required by default. Wrap the type in Option<T> to make it optional. Flags (--flag) are optional by default; add .required(true) to make them mandatory.
Sources
- clap crate docs: API reference and derive guide
- clap derive reference: All derive attributes
Related Glossary Terms
- Struct: clap's derive API annotates structs to define CLI arguments
- Enum: Subcommands are typically defined as Rust enums
- Serde: Often paired with clap to load config from files
Keep Reading
- Learn Rust in 2026: CLI tools are the most common first Rust project
- Best Way to Learn Rust in 2026: building a CLI as a learning project
