---
title: 'cargo-generate: The Consultant''s Secret Superpower

  '
teaser: Lessons and guidelines from Rust, Ruby, and Python project generators.
tags: rust
author: Mike Burns
published_on: 2023-12-22
---

We have [two][] teams [dedicated][] to new apps, so it's no surprise that we're
drawn to Rust's cargo-generate tool.

[two]: https://thoughtbot.com/early-stage-product-validation "Early Stage & Product Validation"
[dedicated]: https://thoughtbot.com/mvp-mobile-design-development "MVP, Mobile & Design"

The project's [documentation][] is a good starting point. We'd like to pass on
some guidelines and lessons we've learned while using it.

[documentation]: https://cargo-generate.github.io/cargo-generate/index.html

## Always specify the cargo-generate version

Get it right before it's a problem: [require][] a minimal cargo-generate version
from the start. This way you'll detect incompatibilities as you go, and it will
prevent colleagues from being bitten by missing features or version mismatches.

```toml
[template]
cargo_generate_version = ">=0.18.0"
```

[require]: https://cargo-generate.github.io/cargo-generate/templates/require_version.html

## Use sub-directories

Another technique to get right from the start: the git repo should not be the
template base. This way you can add all the metadata to the git repo root
without worrying about explicitly excluding the files.

Make a [directory][] called `template` and stuff the `cargo-generate.toml` in
there.

[directory]: https://cargo-generate.github.io/cargo-generate/usage.html#templates-in-subfolders

## Schedule CI

The documentation [explains][] how, but does not emphasize: _you should do this_.
Automatically using the template once a week is a simple way to be alerted to
problems. Knowing that the template has issues ahead of time means you can
build that into the setup time for the next project without any surprises.

[explains]: https://cargo-generate.github.io/cargo-generate/templates/authoring.html

## Generate a setup script and README documentation

The setup script defines the structure for all future one-off scripts in the
generated project. We use [the xtask pattern][], so the `cargo xtask setup`
task comes defined by our templates.

[the xtask pattern]: https://github.com/matklad/cargo-xtask

The generated README documents how to set up the project by running the setup
script.

## Push what you can into libraries

The generator is used once, so if you need a change after the project has been
created then the generator is of no help. As much as possible, use the
generator to define a structure for your project, but not the specifics.

Put another way, you actually want your template to change very little. Every
time you make a change, consider whether there's a way to apply it to existing
apps instead.

## The template is company policy

It's one thing to say "we use cargo workspaces", but it's another thing to
codify it into the actual tool you use to create apps. This has some
implications.

The git repo and its pull requests serve as a record of decisions. We
encourage you to make heavy use of that as a place to record the [story][] of
why a change is made, what factors lead to that decision, and what the other
options were.

[story]: https://thoughtbot.com/blog/storytellers

The discussion and decisions require an important factor: buy-in. We want to
ensure that our developers _want_ to use our templates. They should see it as
better than starting from scratch, and it should provide them with tools that
they understand and appreciate. The governance of the template repo plays a
critical role in advancing that agenda.

## Generalize

These lessons come not just from cargo-generate but also from our years spent
working on [Suspenders][] and also time spent on an internal Django template. For
other consultants switching to Rust, remember the lessons you've learned
elsewhere and see how they do (or don't!) fit in the new context.

[Suspenders]: https://github.com/thoughtbot/suspenders
