External Publication
Visit Post

Alternative to `cargo new` templates: examples as build-target templates

Rust Internals [Unofficial] March 2, 2026
Source

One option could be:

$ cargo new --bin --from clap
... list all examples ...
$ cargo new --bin --from clap demo

would create

Cargo.toml:

...

[dependencies]
clap = { version = "4.5.30", features = ["derive" }

src/main.rs:

use clap::Parser;

/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
    /// Name of the person to greet
    #[arg(short, long)]
    name: String,

    /// Number of times to greet
    #[arg(short, long, default_value_t = 1)]
    count: u8,
}

fn main() {
    let args = Args::parse();

    for _ in 0..args.count {
        println!("Hello {}!", args.name);
    }
}

There are several routes we can take for copying the example:

  • If its examples/foo.rs, copy that in. If its a examples/foo/main.rs then copy it to main.rs, lib.rs, or mod.rs along with the rest of the directory
    • Apparently, cargo doesn't discover examples/foo/lib.rs though lib examples are supported by setting crate-types in Cargo.toml
  • Should we limit lib examples to only being used for mods and lib.rs? Or do we auto-append fn main()?
  • Should we limit bin examples to main.rs, tests, and build scripts? Or copy them, over and have main.rs be dead code?

For mods, maybe this would be:

$ cargo new --mod src/foo --from clap demo

If the mod exists, it will be used as the parent for the new mod. If it isn't, then it will be used.

For Cargo script, it would be:

$ cargo new --file --from clap demo

where it defaults the filename to the example name if a path isn't given.

Thoughts:

  • Not thrilled with multi-valued flags
  • We could accept a PackageIdSpec for non-dependency packages
    • Full-form is verbose and hard to write out (registry+https://github.com/rust-lang/crates.io-index#clap@4.5.56)
    • If we support short form (clap, clap@4.5.56), we could get some dependency confusion going on (thought you were adding an example from a package in a local dependency that points to git or an alt registry but instead get from crates.io. If we support a default registry in Cargo.toml as suggested at #t-cargo > Making alternative registries nicer to use @ , then this might limit the impact but not remove it.

Discussion in the ATmosphere

Loading comments...