Lesson 3

Your first Cargo project

Create a binary package with cargo new, understand Cargo.toml and Cargo.lock, and walk through the check, build, run, test and doc cycle.

Level
Intro
Duration
25 min
Updated

From an installed toolchain to your first package

In the previous lesson you installed rustup, rustc, Cargo and the rest of the ecosystem’s tooling. Now it is time to use them: instead of compiling a single file with rustc, you will create a package managed by Cargo, the way virtually all real Rust code gets built.

This lesson walks through the full cycle: creating the package, understanding what each generated file describes, and running the commands you will use every day while you write code.

Step map

  • TASK · no projectno Cargo.toml yet
  • TOOL · scaffoldingconventional layout
  • OUTCOME · Cargo.toml + src/main.rsalready builds and runs
01 / 04CARGO NEW · PACKAGE · BINARY

Create the package

Create and enter the packagemacOS · Linux · PowerShell
cargo new project_name
cd project_name

Cargo generates this structure:

Package structure

project_name/

  • Cargo.toml
  • .gitignore
  • src/
    • main.rs

And src/main.rs already contains a program that compiles and runs:

src/main.rsCompiles
fn main() {
    println!("Hello, Rust!");
}

Read the manifest

Cargo.toml
[package]
name = "project_name"
version = "0.1.0"
edition = "2024"

# Filled in with `cargo add`, not by hand.
[dependencies]

Cargo.toml is the single source of truth for what your package depends on and which versions. Cargo.lock, generated alongside it on the first build, pins the exact resolved versions so the build is reproducible on any machine; never edit it by hand.

The check → build → run cycle

Check, build and runmacOS · Linux · PowerShell
cargo check
cargo build
cargo run

cargo check is the fastest because it does not produce final machine code. cargo build leaves an unoptimized binary at target/debug/. cargo run recompiles only if something changed and runs the result.

For an optimized build:

Build in release modemacOS · Linux · PowerShell
cargo build --release

The optimized binary ends up at target/release/, at the cost of a slower compile than debug mode.

Test and document

Run the tests and generate the documentationmacOS · Linux · PowerShell
cargo test
cargo doc --open

cargo test discovers and runs any function marked #[test] in the crate; there is nothing extra to configure. cargo doc --open generates an HTML site from the /// comments on the public API and opens it in your browser.

What this lesson does not cover

  • It does not go deep into the full difference between debug and release profiles (optimizations, debug symbols, compile times).
  • It does not explain how to read a compiler error when something fails to build: that is the next lesson.
  • It does not cover real external dependencies beyond cargo add/cargo rm, already seen in the previous lesson.

What’s next

With a package that builds, runs, tests and documents itself, the next lesson teaches you how to read the compiler’s messages when something fails: what each part of an error means and how Rust guides you toward a fix.

Summary

  • cargo new creates the minimum package structure (Cargo.toml, src/main.rs, .gitignore); --lib generates a library instead.
  • Cargo.toml declares the package and its dependencies; Cargo.lock pins the exact resolved versions and is never hand-edited.
  • cargo check checks types without producing a binary; cargo build produces one at target/debug/; cargo run compiles if needed and runs; --release optimizes and compiles more slowly.
  • cargo test runs any #[test] function; cargo doc --open generates and opens HTML documentation from /// comments.

Sources