tech

Building a CLI Tool in Rust

rustclitooling

I recently built a small CLI tool in Rust to manage my local notes. Here are a few things I learned along the way.

Structuring with Clap

Clap is the de facto standard for argument parsing in Rust.

use clap::{Parser, Subcommand};

#[derive(Parser)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    List,
    Add { title: String },
    Delete { id: u32 },
}

Error Handling

Using anyhow for application-level errors keeps things clean:

use anyhow::Result;

fn run() -> Result<()> {
    let cli = Cli::parse();
    match cli.command {
        Commands::List => list_notes()?,
        Commands::Add { title } => add_note(title)?,
        Commands::Delete { id } => delete_note(id)?,
    }
    Ok(())
}

File Storage

For a simple local tool, JSON files work well as a storage backend. No database, no config — just a ~/.notes.json file.

The full crate weighs under 100 lines of meaningful code. Sometimes small tools are the most satisfying to build.