Lesson 3 of 94
Installing Rust & Cargo
This lesson gets Rust installed and walks through the tools you will use every day. By the end you will be able to create a project, run it, add a library, lint it, format it, and build a release binary.
Rust tools at a glance
| Rust | What it does |
|---|---|
rustup |
Installs and switches compiler versions |
rustc |
The compiler (you rarely call it directly) |
cargo |
Build tool, dependency manager, test runner |
Cargo.toml |
Project and dependency description |
| crates.io | Public library registry |
| A crate | A unit of compilation and distribution |
cargo clippy |
Linter |
cargo fmt |
Formatter |
cargo doc |
API documentation generator |
#[test] + cargo test |
Built into the language |
| Editions 2021, 2024 | Opt-in language changes |
1. Install Rust with rustup
On macOS or Linux:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shOn Windows, download and run rustup-init.exe from rustup.rs. It will ask you to install the Visual Studio C++ build tools, which Rust uses for linking.
Open a new terminal and check the install:
rustc --version
cargo --version
rustup --versionrustc 1.94.1 (e408947bf 2026-03-25)
cargo 1.94.1 (29ea6fb6a 2026-03-24)
rustup 1.29.0 (28d1352db 2026-03-05)Your version numbers will be newer. Rust releases a new stable version every six weeks, and new versions compile old code.
2. Keep Rust up to date
rustup update # update to the latest stable release
rustup show # show installed toolchains
rustup component add clippy rustfmt rust-analyzerRust developers normally just run the latest stable. Backward compatibility is taken very seriously, so updating is routine.
3. Set up your editor
- VS Code: install the rust-analyzer extension. It gives you completion, inline types, go-to-definition, and inline errors.
- IntelliJ IDEA: install RustRover or the Rust plugin.
Both show the type of every variable inline. Turn this on: it helps a lot while you learn.
4. Create your first project
cargo new hello_rust
cd hello_rustCargo creates this layout:
hello_rust/
├── Cargo.toml # like pom.xml: name, version, dependencies
├── .gitignore # ignores target/
└── src/
└── main.rs # the program entry pointsrc/main.rs already contains a program:
fn main() {
println!("Hello, world!");
}Hello, world!fn main() is a free-standing function. The ! in println! means it is a macro, which the next lesson explains.
5. Build and run
cargo run Compiling hello_rust v0.1.0 (/home/you/hello_rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.52s
Running `target/debug/hello_rust`
Hello, world!cargo run compiles and then runs. Other everyday commands:
cargo build # compile only; binary goes to target/debug/hello_rust
cargo check # type-check without producing a binary (fastest feedback)
cargo build --release # optimized build; binary goes to target/release/hello_rust
cargo clean # delete target/Use cargo check constantly while writing code. It is much faster than a full build because it skips code generation.
6. Debug vs release builds
Debug builds compile fast and run slowly. Release builds compile slowly and run fast. The difference is often 10x to 50x in speed, so never benchmark a debug build.
cargo run --releaseRust code is compiled ahead of time to machine code, so the release binary starts instantly and is fast from the first call, with no warm-up.
7. Cargo.toml
[package]
name = "hello_rust"
version = "0.1.0"
edition = "2024"
[dependencies]Crate names on crates.io are globally unique, first come first served.
8. Add a dependency
Use cargo add, which edits Cargo.toml for you:
cargo add rand[dependencies]
rand = "0.9"The version "0.9" means "any compatible 0.9.x version" (semantic versioning), not exactly 0.9.0. The exact versions that were resolved are recorded in Cargo.lock. Commit Cargo.lock for applications, so every build uses the same versions.
Crates can have optional features:
cargo add tokio --features full
cargo add serde --features derive[dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }Cargo downloads source code and compiles it on your machine. The first build of a project with many dependencies is slow. After that, everything is cached in target/.
9. Read compiler errors
Rust's compiler errors are famously helpful. Put this mistake in src/main.rs:
fn main() {
let total = 42;
println!("{}", totl);
}cargo checkerror[E0425]: cannot find value `totl` in this scope
--> src/main.rs:3:20
|
3 | println!("{}", totl);
| ^^^^ help: a local variable with a similar name exists: `total`Every error has a code. Run rustc --explain E0425 to get a full explanation with examples. Read the whole message, including the help: lines: they very often contain the exact fix.
10. Lint with Clippy
Clippy knows hundreds of patterns that compile but are not idiomatic or are likely bugs.
fn main() {
let numbers = [3, 1, 4];
let mut i = 0;
while i < numbers.len() {
println!("{}", numbers[i]);
i += 1;
}
}3
1
4This program is correct, but cargo clippy suggests a cleaner loop. Treat Clippy warnings the way you treat SpotBugs findings: read them, and fix most of them. They are one of the fastest ways to learn idiomatic Rust.
11. Format with rustfmt
cargo fmt # format every file in the project
cargo fmt --check # fail if anything is unformatted (use this in CI)The whole Rust ecosystem uses the same formatter with the same defaults, so there are no style debates. 4-space indentation, snake_case for functions and variables, and PascalCase for types are universal.
12. Generate documentation
cargo doc --openThis builds HTML documentation for your project and every dependency, then opens it in your browser. You get documentation for every library you use, matched to the exact versions in your project, available offline.
13. Editions: Rust's language versions
Rust adds features across compiler releases, and old code keeps compiling. For the rare changes that would break old code, Rust uses editions: 2015, 2018, 2021, and 2024.
- Each crate chooses its edition in
Cargo.toml(edition = "2024"). - Crates on different editions work together in the same program.
cargo fix --editionmigrates most code automatically.
This course uses edition 2024 throughout.
14. Run a single file without Cargo
For a quick experiment you can call the compiler directly:
rustc main.rs # produces an executable called `main` (or main.exe on Windows)
./mainFor anything with dependencies, use Cargo. In practice, almost everyone uses Cargo even for experiments, or the Rust Playground.
Summary
| Task | Command |
|---|---|
| Create a project | cargo new name |
| Type-check quickly | cargo check |
| Build and run | cargo run |
| Optimized build | cargo build --release |
| Add a library | cargo add crate_name |
| Lint | cargo clippy |
| Format | cargo fmt |
| Run tests | cargo test |
| Open documentation | cargo doc --open |
Next: Hello World & Printing Output, where you learn println! formatting, which every later example uses.
