External Publication
Visit Post

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

Rust Internals [Unofficial] March 5, 2026
Source

bushRAT:

I don't think we want to directly pull examples from existing crates as templates.

...

I feel like you'd want an explicit template item to pull from, which would just be a crate (either a single-file script or a more typical crate).

Yes, dependencies are an issue. There is required-features but that doesn't solve everything.

Adding a new template system also has a lot of complications to work through:

  • Associating: how does a package declare a relationship to its templates when those templates depend on it? This is one of the problems we are having with the "recommended-bins" idea for libraries to redirect people to their associated binary (e.g. a cargo install foo and tell people to instead run cargo install foo-cli)
  • Being able to tell what to copy over. With an example this is easy. With a whole package, it gets more complicated.
  • MSRV: if this ends up requiring an MSRV bump, it will take even longer before people can use it
  • Bootstrapping: packages have examples today. Maintainers would then need to write out templates and likely dual-source some examples as templates

bushRAT:

The benefit of the new frontmatter system is you could now have single-file templates, which would just look identical to examples anyway.

Nothing stops people from putting frontmatter in their examples today and in fact it might be useful to do so as people get confused reading an example and understanding how to replicate it. Even if we do example templates, we could merge the frontmatter in as well.

bushRAT:

it could also have explicit support for a default

Having defaults would be an interesting idea regardless of what is used as the example.

bushRAT:

If templates are meant to include extending an existing project, not just creating a new one, I feel like we need either a build script or a proc-macro to handle merging a template into a project. Take tokio and clap as examples. They each could have templates for a new binary project, and ideally you could slap tokio onto an existing project and it would handle taking the contents of your existing main function and placing them into the new async version for you. This probably can't be done by Cargo since it's far too contextual, but I think either a merge.rs or a merge proc-macro could do it.

For clap, I don't think there is anything I would do for a merge operation. For CLI testing, I could see customizing the environment variable read for CARGO_BIN_EXE_*. But I've accepted the idea of not doing that.

Build scripts as is are getting a lot of scrutiny for security a and build performance and we should be looking for ways to remove their need or consolidate down to fewer of them. At least with build scripts, you can depend on everything and then audit it before running. Here, you would be running foreign code and the workflow for auditing it is worse and you wouldn't even know the version used.

If we have a merge.rs, we then also need merge-dependencies and the run on effects of that (e.g. cargo new time to compile all of this). We also then need a more native way of validating templates while before I was assuming we could rely on third-party tools which then further extends the API surface in this design work which is one of the things this design was trying to minimize.

bushRAT:

I do think a TUI more like npm init would be useful, especially for new users. For one thing, it could give you an option to search for a template from crates.io, select features and dependencies, etc. I imagine you could add a --interactive/-I switch to turn this on (in order to preserve the current fast non-interactive command).

There is interest in adding interactive modes to Cargo commands. We are testing the waters with a TUI for cargo tree, see GitHub - orhun/cargo-tree-tui: Ratatuifying Rust's package manager · GitHub

kornel:

For discoverability in Cargo you'd also want to have descriptions for them, which the package has, but targets don't.

Good point about descriptions.

Discussion in the ATmosphere

Loading comments...