Initialize your Rust project
The template has no Cargo manifest or starter package. Choose the structure your project needs.
rust-toolchain.toml selects the stable Rust channel with the default profile, including rustfmt, Clippy, and local Rust docs.
mise.toml enables Mise to read that file and install Rustup and the requested toolchain when needed. Run mise install
after cloning. Keep Rust's channel, profile, components, and targets in rust-toolchain.toml, without a duplicate Rust entry
under Mise's [tools].
Rustup also reads the same file when you run cargo directly. The stable channel moves over time; mise.lock does not
freeze its compiler version. Run mise upgrade rust to update it, then verify your project. If you need an exact compiler
version, set channel to that version in rust-toolchain.toml.
Root package
From the repository root, choose one:
# Binary package (CLI or application).
cargo init --bin --name my-app .
# Library package.
cargo init --lib --name my-lib .
Cargo creates a root Cargo.toml and src/ directory. Run a binary with cargo run, or test either package type
with cargo test. Set license = "MIT" in the package manifest if retaining the template's license,
and publish = false for a package that should stay private.
Cargo workspace
First create the initial package from the repository root:
cargo new --bin --vcs none crates/my-app
For a library instead, use cargo new --lib --vcs none crates/my-lib.
--vcs none prevents Cargo from creating a nested Git repository; packages use the project's existing repository.
Then manually create a root Cargo.toml containing:
[workspace]
members = ["crates/*"]
resolver = "3"
[workspace.package]
edition = "2024"
license = "MIT"
In the initial package's Cargo.toml, replace its edition entry with edition.workspace = true
and add license.workspace = true. Set publish = false for packages that should stay private.
Keep at least one package in the workspace.
crates/ is a directory convention, not the workspace's name. The root manifest defines the workspace.
Add more packages with cargo new --bin --vcs none crates/my-cli or cargo new --lib --vcs none crates/my-lib.
The crates/* pattern includes them automatically, so you don't need to edit the root manifest for each addition.
Check each package's manifest for the shared edition and license settings.
Run or test a package by the name in its Cargo.toml:
cargo run -p my-app
cargo test -p my-lib
Workspaces share a root Cargo.lock and target/ directory.
Add Rust checks
After initializing either structure, run cargo generate-lockfile and commit Cargo.lock.
Add this task to mise.toml:
[tasks.check]
description = "Check Rust formatting, lints, and tests"
run = [
"cargo fmt --all -- --check",
"cargo clippy --workspace --all-targets --locked -- -D warnings",
"cargo test --workspace --locked",
]
Run mise run check locally. These commands work for a root package or a workspace.
Add a Rust job to .github/workflows/ci.yml that installs Rust through jdx/mise-action@v4
with install_args: rust and runs mise run check. The template's CI runs repository checks until you add that job.
Commit lockfile changes after adding packages or dependencies, and add tests for your application's behavior.