Skip to content

clap

Developer UtilitiesCLI/UtilsRust

What it is

clap is Rust's command-line argument parser, generating parsing, validation, help text and shell completions from a derived struct.

Annotate a struct with #[derive(Parser)]; fields become flags and arguments. Subcommands are an enum. Doc comments become the help text.

Installation

cargo add clap --features derive

Getting started

The smallest useful thing you can do with it, and what each part means.

Arguments from a struct
use clap::Parser;

/// Manage a book library.
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    /// Path to the library file
    #[arg(short, long, default_value = "library.json")]
    file: PathBuf,

    /// Increase output verbosity
    #[arg(short, long, action = clap::ArgAction::Count)]
    verbose: u8,

    /// Titles to add
    titles: Vec<String>,
}

let cli = Cli::parse();   // exits with help/errors automatically
The doc comments are the help text, so documentation and CLI output cannot diverge. ArgAction::Count turns -vvv into verbose = 3.
Subcommands
#[derive(Parser)]
struct Cli {
    #[command(subcommand)]
    command: Command,
}

#[derive(clap::Subcommand)]
enum Command {
    /// Add a book
    Add { title: String, #[arg(long)] year: Option<u16> },
    /// Remove a book
    Remove { id: u32 },
}

match cli.command {
    Command::Add { title, year } => add(title, year),
    Command::Remove { id } => remove(id),
}
The match is exhaustive, so adding a subcommand is a compile error until it is handled — the parser and the dispatch cannot drift apart.

Advanced usage

Where the library earns its place over a simpler alternative.

Validation, environment and completions
#[derive(Parser)]
struct Cli {
    #[arg(long, env = "API_TOKEN", hide_env_values = true)]
    token: String,

    #[arg(long, value_parser = clap::value_parser!(u16).range(1..=65535))]
    port: u16,

    #[arg(long, value_enum, default_value_t = Format::Json)]
    format: Format,
}

// Generate a completion script at build time or behind a hidden flag.
clap_complete::generate(Shell::Zsh, &mut Cli::command(), "library", &mut io::stdout());
The env attribute lets a flag fall back to an environment variable, and hide_env_values keeps a token out of the help output.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Compile error about ArgAction
Version 3 and 4 differ substantially. Check which version the example targets — most older tutorials are for v3.
Long compile times
clap with derive is heavy. Disable default features and enable only what you need if binary size matters.

Best practices

  • Use the derive API; the builder is only needed for arguments constructed at runtime.
  • Write doc comments — they become the help text.
  • Use value_parser for ranges and enums so invalid input is rejected before your code runs.
  • Ship completions with the binary; it is a small change with a large usability payoff.

Background

Why it exists, and what it was reacting to.

clap's derive API turned argument parsing into a matter of describing a struct. Version 4 sharpened error messages and cut compile time and binary size considerably.