Guide contents

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:

Terminal
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

On 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:

Terminal
rustc --version
cargo --version
rustup --version
Output
rustc 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

Terminal
rustup update          # update to the latest stable release
rustup show            # show installed toolchains
rustup component add clippy rustfmt rust-analyzer

Rust 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

Terminal
cargo new hello_rust
cd hello_rust

Cargo creates this layout:

Text
hello_rust/
├── Cargo.toml     # like pom.xml: name, version, dependencies
├── .gitignore     # ignores target/
└── src/
    └── main.rs    # the program entry point

src/main.rs already contains a program:

Rust
fn main() {
    println!("Hello, world!");
}
Output
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

Terminal
cargo run
Output
   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:

Terminal
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.

Terminal
cargo run --release

Rust 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

TOMLCargo.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:

Terminal
cargo add rand
TOMLCargo.toml
[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:

Terminal
cargo add tokio --features full
cargo add serde --features derive
TOMLCargo.toml
[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:

Rust✗ does not compile · E0425
fn main() {
    let total = 42;
    println!("{}", totl);
}
Terminal
cargo check
Output
error[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.

Rust
fn main() {
    let numbers = [3, 1, 4];
    let mut i = 0;
    while i < numbers.len() {
        println!("{}", numbers[i]);
        i += 1;
    }
}
Output
3
1
4

This 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

Terminal
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

Terminal
cargo doc --open

This 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 --edition migrates 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:

Terminal
rustc main.rs   # produces an executable called `main` (or main.exe on Windows)
./main

For 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.