Comparison of Rust 🦀 CLI Prompts: cliclack, dialoguer, promptly, and inquire

Let's compare 4 different command line prompt crates by running their basic examples: cliclack, dialoguer, promptly, inquire.

Comparison of Rust 🦀 CLI Prompts: cliclack, dialoguer,  promptly, and inquire

Let's compare 4 different command line prompt crates by running their basic examples.

cliclack

Crate: https://crates.io/crates/cliclack
GitHub: https://github.com/fadeevab/cliclack

cliclack is a "Clack for Rust" (clone of npm @clack/prompts).

How to run:

cargo run --example basic

Result:

The example is taken from https://github.com/fadeevab/cliclack

Theme support:

Full example: https://github.com/fadeevab/cliclack/blob/main/examples/theme.rs

Sample code:

intro("create-my-app")?;

let path: String = input("Where should we create your project?")
    .placeholder("./sparkling-solid")
    .validate(|input: &String| {
        if input.is_empty() {
            Err("Please enter a path.")
        } else if !input.starts_with("./") {
            Err("Please enter a relative path")
        } else {
            Ok(())
        }
    })
    .interact()?;
    
let number: u8 = input("Input a number (not greater than 256)").interact()?;

outro("You're all set!")?;

dialoguer

Crate: https://crates.io/crates/dialoguer
GitHub: https://github.com/mitsuhiko/dialoguer

How to run:

cargo run --example input

Result:

Sample code:

let mail: String = Input::with_theme(&ColorfulTheme::default())
    .with_prompt("Your email")
    .validate_with({
        let mut force = None;
        move |input: &String| -> Result<(), &str> {
            if input.contains('@') || force.as_ref().map_or(false, |old| old == input) {
                Ok(())
            } else {
                force = Some(input.clone());
                Err("This is not a mail address; type the same value again to force use")
            }
        }
    })
    .interact_text()
    .unwrap();

promptly

Crate: https://crates.io/crates/promptly
GitHub: https://github.com/anowell/promptly

How to run:

cargo run --example basic

Result:

Sample code:

use promptly::{prompt, prompt_default, prompt_opt};

// Prompt until a non-empty string is provided
let name: String = prompt("Enter your name")?;

// Prompt for other `FromStr` types
let age: u32 = prompt("Enter your age")?;

// Prompt for optional paths with path completion. Returns `None` if empty input.
let photo: Option<PathBuf> = prompt_opt("Enter a path to a profile picture")?;

// Prompt Y/n with a default value when input is empty
let fallback = prompt_default("Would you like to receive marketing emails", true);

// Prompt for a url using the url crate (requires either 'nightly' or 'url' feature)
let website: Url = prompt("Enter a website URL");

inquire

Crate: https://crates.io/crates/inquire
GitHub: https://github.com/mikaelmello/inquire

How to run:

 cargo run --example expense_tracker --features="date macros"

Result:

The example is taken from https://github.com/mikaelmello/inquire

Sample code:

let _payee = Text::new("Payee:")
    .with_validator(required!("This field is required"))
    .with_autocomplete(&payee_suggestor)
    .with_help_message("e.g. Music Store")
    .with_page_size(5)
    .prompt()?;

let amount: f64 = CustomType::new("Amount:")
    .with_formatter(&|i: f64| format!("${i}"))
    .with_error_message("Please type a valid number")
    .with_help_message("Type the amount in US dollars using a decimal point as a separator")
    .prompt()
    .unwrap();