How to build a CLI app

Cli
To build a CLI app in Rust, use the `clap` crate for argument parsing and the `anyhow` crate for ergonomic error handling, then compile the binary with `cargo build`.

To build a CLI app in Rust, use the clap crate for argument parsing and the anyhow crate for ergonomic error handling, then compile the binary with cargo build. This combination provides a robust, type-safe foundation that handles help messages, subcommands, and error reporting automatically.

Start by adding dependencies to your Cargo.toml. clap is the industry standard for CLI parsing, while anyhow simplifies error propagation so you don't have to define custom error types for every function.

[dependencies]
clap = { version = "4.5", features = ["derive"] }
anyhow = "1.0"

In your src/main.rs, define a struct annotated with #[derive(Parser)] to map command-line arguments to Rust fields. Clap automatically generates help text (--help) and validates inputs based on your struct definition.

use clap::Parser;
use anyhow::Result;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// The input file to process
    input: String,

    /// Output directory
    #[arg(short, long)]
    output: Option<String>,

    /// Enable verbose logging
    #[arg(short, long)]
    verbose: bool,
}

fn main() -> Result<()> {
    let args = Args::parse();

    if args.verbose {
        println!("Verbose mode enabled");
    }

    println!("Processing: {}", args.input);
    
    if let Some(out) = args.output {
        println!("Outputting to: {}", out);
    } else {
        println!("Outputting to stdout");
    }

    Ok(())
}

Run the application with cargo run. Clap will automatically handle missing arguments, invalid types, and display a formatted help menu if the user runs the binary with --help or -h. For example, running cargo run -- --input data.txt -v will parse the arguments into the Args struct, allowing you to access args.input and args.verbose directly in your logic.

If you need to build a release binary optimized for production, use cargo build --release. This compiles the code with optimizations enabled, resulting in a significantly faster and smaller executable. You can then run the binary directly from the target/release folder or install it globally using cargo install --path . if you have a Cargo.toml configured for installation.

For more complex applications with subcommands (e.g., myapp create, myapp delete), nest structs inside the main Args struct using the #[command(subcommand)] attribute. This pattern scales well for tools like git or docker clones, keeping your code modular and your CLI interface intuitive.