[Pre-RFC]: cargo new templates
Start Date: 2020-04-01
RFC PR: rust-lang/rfcs#0000
Rust Issue: rust-lang/cargo#3506
Add the ability to pass a template to
cargo new when creating a new project.
Add an interactive mode to
cargo new if it is run without arguments. This would take the user through a series of questions(i.e. Name, initialize git repo, include
We’re doing this for two reasons. One, there is a disagreement between members of the community on whether or not the default
cargo new template should include a
README. The hope is the interactive mode would allow the user to choose whether or not they want a
The other is allowing users to create new projects using their own templates.
The expected outcomes are:
a more user-friendly new project workflow (interactive mode)
READMEout of the box
support community-member-made templates
Let’s create a new project using Cargo. Navigate to your projects directory (or wherever you decided to store your code). Then, on any operating system, run the following:
Cargo will run you through its interactive mode and ask you the following questions:
Project Name: <write the name of the project, default: hello_cargo>
Binary or library: <write “bin” or “lib”, default: bin>
Initialize git repo: <write y or n, default: y>
Create README: <write y or n, default: y>
If you want to skip the questions and use the defaults, you can pass the flag
--yes to the
cargo new command like so:
cargo new -y
You can also skip questions by passing the name of the project to the command:
cargo new my_project
Once you become more familiar with Rust, you may have your preferred project folder structure. For this, you might be interested in creating a template. The
cargo new command supports templates via git repositories. You can use it by running:
cargo new <name-of-project> <template-repository-URL>
cargo new without any flags will initialize an interactive mode, similar to how
cargo-generate works. The user will be prompted for the questions and provide input. Once the input is collected,
cargo will create the project and add the files.
We will add a check for the flag
--yes. If this is passed, we will skip the questions and provide the defaults.
If a name is provided after
cargo new without a URL to a template, it will follow the behavior of the
If a name is provided after
cargo new along with a URL to a template, Cargo will create a directory with the provided name and copy the files from the template into the new directory.
Don’t fix it if it’s not broken
This introduces unnecessary complexity to the
cargo project. Creating a new project with
cargo new suffices. Users can add a
README.md or modify the project without much hassle after creating a new project.
cargo-generate project solves the template issue. The cost of bringing this functionality into the core features of
cargo may be more than the benefits it would bring.
Unmaintained templates -> negative effect on the community
cargo supporting templates, this may lead to a large influx of community-created templates. Over time, this will grow and many will go unmaintained. When community members try to use these templates, it may lead to issues that could have a hurt on the community.
Rationale and alternatives
This is the best design because it keeps it simple while providing an upgraded UX to both users using the default template and users using their own templates. The interactive mode will be helpful for those who are less familiar with CLIs (i.e. they might not realize they can configure their project with specific flags).
Interactive mode will also encourage documentation out of the box by asking if the user would like a
README.md created for their new project.
The templates are kept simple. Cargo can look at a git repository and copy the files over. This solution provides the simplest implementation without overcomplicating things.
The impact of not doing this is:
not encouraging users to include
READMEs in their project
asking users to reach for other tools to use their own templates
Does this exist in other programming languages?
Looking at other programming communities, similar implementations exist.
In the JS community, two similar concepts have been implemented.
This initializes your
package.json (same as
Cargo.toml). It asks a series of questions then provides you with a
pacakge.json filled out. The difference is that it only creates this file and no other files.
Note you can skip the questionnaire by
The npm CLI also added a convention that allows you to initialize a project for any package following the convention:
create-<initializer> which can then be used to generate a new project with
npx (similar to
npm init). This has been implemented by popular projects such as React and Next.
cargo new, which is
gatsby new. Here is how it works:
gatsby newwith no flags/arguments runs an interactive shell asking for the name of your project and which starter/template to use
gatsby new [<site-name> [<starter-URL>]]can also start a new project using a URL to a starter (template) from GitHub. Example
gatsby new my-awesome-blog-site https://github.com/gatsbyjs/gatsby-starter-blog
npx degit sveltejs/template my-svelte-project
The Svelte framework follows a similar pattern to Gatsby. It uses a project scaffolding tool called
degit. It follows the pattern
npx degit <user/repo> <name-of-project>. You can read more about it in the
It appears there is a
pip package created by the community called
pastescript, which, “[creates] file layouts for packages.” You can use it by running:
paster create --template=basic_package MyPackage
bundle gem my_app
This runs through an interactive shell that asks about tests, a license, a code of conduct and it creates a
README for you. Read more here.
rails new my-app
Ruby on Rails, a popular framework in the Ruby community, includes a script to scaffold out a new project, which includes a
Creates a new Go project and includes the following:
vendor/. Read more here.
go mod init
Creates a new Go module, which adds the
go.mod file. Read more here.
bsb -init my-new-project -theme basic-reason
swift package init
This creates a new Swift package. It includes the following:
Tests. Read more here.
Has the community suggested this before? Are there crates that solve this problem already?
A similar RFC for cargo templates was written back in April 2017 and shared on the internals forum. It seemed like there were a lot of discussions, but no consensus reached.
The community has also created two crates that solve similar problems:
README.mdfrom doc comments.
cargo-generate: a developer tool to help you get up and running quickly with a new Rust project by leveraging a pre-existing git repository as a template
In addition, there was a lot of discussion both from the Cargo team and the community on this issue. It has been decided that there still remains disagreement among both the Cargo team and the community on how to solve this, hence why this RFC seems to be the logical next step.
What lessons can we learn from what other communities have done here?
There are pros and cons to having templates or some type of template ecosystem. I think the biggest question is **who will maintain them?**It may not be directly related, but it's an important point to consider should templates be added to
Community maintained templates
In the Gatsby.js community, there are +300 starters. Only a select few are maintained by the Gatsby.js core team. The rest are added by community members.
- Community members can contribute
- There is a wilder selection of options
- Members can abandon their starters which can negatively impact the community
Core team maintained templates
create-react-app and the
create-next-app templates, those are maintained by core team members (i.e. a select group of individuals). There are some variations to the templates (i.e. regular vs. TypeScript).
- Creates a “standard”
- Requires dedicated maintainers
- Less community involvement (beyond direct contributions)
Some questions that may require further discussion depending on how this RFC goes.
Questions that fall in the scope of this RFC:
What should the
READMEinclude that is created for the default template?
Where do the docs need to be updated?
What security measures need to be accounted for when Cargo clones from third-party templates? (i.e. what if a template contains a malicious file?)
Questions that could be answered after the implementation:
What guidelines should the Cargo team provide for creating templates?
Will there be any “official” templates?
Should templates live in a central place? (i.e. in one repo in the
Related issues that are considered out of scope for this RFC:
using local templates
using templates from private repos
Nothing at the moment beyond the questions I noted for after the implementation.