Setting up Rust: rustup, Cargo and edition 2024
Installing with rustup, cargo new and cargo add, the Cargo.toml fields that matter, cargo check, run, test and fmt, clippy, and when a workspace helps.
rustup and toolchains
Rust is installed through rustup, a version manager rather than a package. It installs the toolchain — rustc, cargo, the standard library — and lets you switch versions per project, which is why a 2021-edition crate and a 2024-edition crate can live side by side.
rustup show # installed toolchains and the active one
rustup update # upgrade every channel
rustup toolchain install nightly # opt in to a channel per project
rustup component add clippy rustfmt
rustup target add x86_64-unknown-linux-musl
rustup override set 1.85.0 # pin this directory to a version
rustc --version && cargo --version| Channel | What it is |
|---|---|
stable | The default. A new release every six weeks; what you ship against |
beta | The next stable, useful for checking a release will not break you |
nightly | Unstable features behind feature gates; needed by some tooling, never required to ship |
rust-toolchain.toml | A file in the repository pinning the exact channel and components for everyone |
[toolchain]
channel = "1.85.0"
components = ["rustfmt", "clippy"]
targets = ["x86_64-unknown-linux-musl"]Cargo.toml: the manifest
cargo new notes --bin # binary crate; --lib for a library
cargo new --lib notes-core
cargo add clap --features derive
cargo add --dev tempfile
cargo add [email protected][package]
name = "notes"
version = "0.1.0"
edition = "2024" # the language version: 2015, 2018, 2021 or 2024
rust-version = "1.85" # the minimum toolchain you support
description = "A small note manager"
license = "MIT OR Apache-2.0"
[dependencies]
clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
thiserror = "2"
[dev-dependencies]
tempfile = "3"
[profile.release]
lto = "thin"
strip = "symbols"editionis not the compiler version; it is the language rules your crate is parsed and checked under. Dependencies use their own edition, so upgrading yours never breaks them.rust-versionis a promise to users: below it, Cargo reports a clear error instead of a compile failure deep inside your code.- A caret requirement such as
"1.2"allows any1.xat or above1.2. Semver is treated as a guarantee, so an incompatible change must be a new major version. Cargo.lockpins exact versions and belongs in version control for binaries. For libraries it is still committed, and CI can ignore it withcargo updateto test against newer compatible releases.[profile.release]settings change speed, size and build time.lto = "thin"is a good default;codegen-units = 1and fullltoare slow to build and worth it only for final artifacts.
The daily workflow
cargo check # type-check only: seconds instead of minutes
cargo run -- --help
cargo test
cargo test --doc
cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo doc --no-deps --open
cargo tree -d # find duplicated dependency versions
cargo publish --dry-run- Run
cargo checkwhile editing andcargo buildonly when you need a binary. The optimiser and code generator are the slow part and neither is needed to find a type error. cargo clippycatches real mistakes, not just style: a redundant clone, amatchthat is really anif let, a comparison that could bePartialEq. Treat its warnings as errors in CI.- Editor support comes from rust-analyzer, which uses the same check pipeline; inlay hints make inferred types visible without an annotation.
- Add a workspace when two crates need to be built together or share one lock file. It is a
[workspace]table with amemberslist, plus shared dependency versions under[workspace.dependencies]. - Do not fight the borrow checker through an editor plugin that rewrites your code for you. Learn the error, then fix the design — the fix is usually a smaller scope or an explicit clone.
💡
The fastest way to learn Rust is a build loop that stays under a few seconds:
cargo check on save, cargo test when a unit of work is done, clippy before you commit. Compile errors are the tutor, and they cost nothing to read if you do not let them pile up.FAQ
Should I use nightly?
Only when a specific tool needs it. Stable builds everything you ship; nightly is for feature-gated experiments and some formatters and linters. Pin it in
rust-toolchain.toml if you do, so everyone gets the same one.Why does cargo check pass while my editor shows errors?
The editor's rust-analyzer has its own cache and may be running against a different target or feature set. Run
cargo check --all-targets to see the truth, and restart the language server if the two stay out of sync.Related
Modules, crates and project structure Testing, documentation and CI
Last refreshed 2026-09-18.