Chapter 01
Hello, Rust
Installing the toolchain, creating your first project, and understanding how Rust programs are built and run.
Installing Rust
Rust is installed and managed through rustup, the official toolchain installer. It handles installing the compiler (rustc), the package manager and build tool (cargo), and the standard library. It also makes it easy to switch between Rust versions and update them.
Open your terminal and run:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shFollow the prompts - the defaults are fine. Once it finishes, restart your terminal (or run source ~/.cargo/env) so that cargo and rustc are on your PATH.
Verify the installation:
rustc --version
cargo --versionYou should see version numbers for both. rustc is the compiler itself - you rarely call it directly. cargo is what you'll use day to day: it compiles your code, manages dependencies, runs tests, and more.
rustup also installs rustfmt (code formatter) and clippy (linter). You'll use both later. For now, just know they're there.Creating Your First Project
Every Rust project starts with cargo new. This creates a directory with the right structure, a Cargo.toml manifest, and a starter main.rs. We're going to build a webserver over the course of this guide, so let's name it accordingly:
cargo new webserver
cd webserverHere's what Cargo created for you:
webserver/
├── Cargo.toml
└── src/
└── main.rsThat's it - two files. Rust projects are deliberately minimal. There's no framework scaffolding, no config files, no build scripts. Just a manifest and your source code.
Understanding Cargo.toml
Cargo.toml is the manifest for your project. It declares metadata, dependencies, and build configuration. Open it up:
[package]
name = "webserver"
version = "0.1.0"
edition = "2021"
[dependencies]The [package] section has three key fields: name is your crate (Rust's term for a package or library), version follows semver, and edition pins which version of the Rust language your code targets. Edition 2021 is the current standard - it doesn't limit which compiler version you use, it just controls which language features and defaults are active.
The [dependencies] section is empty for now. As we build out the webserver, we'll add crates here - Tokio for async, Serde for JSON, and others. Cargo downloads and compiles them automatically.
Understanding main.rs
Every Rust binary needs a main function - it's the entry point. Open src/main.rs:
fn main() {
println!("Hello, world!");
}A few things to notice right away:
fndeclares a function. No return type means it returns()- Rust's unit type (likevoid).println!is a macro, not a function - that's what the!means. Macros in Rust can do things functions can't, like accepting variable numbers of arguments with format strings. We'll cover macros properly in Chapter 18.- Semicolons are required at the end of statements. Unlike JavaScript or Go, Rust won't infer them.
Compiling and Running
The simplest way to build and run your program in one step:
cargo runYou should see Cargo compile the project, then print Hello, world!. Under the hood, Cargo called rustc to compile src/main.rs into a binary in the target/debug/ directory.
Let's change the message to something relevant to our project. Update main.rs:
fn main() {
println!("Starting webserver...");
println!("Listening on port 8080");
}Run it again with cargo run. Cargo is smart - it only recompiles files that changed, so subsequent builds are faster than the first.
A Tour of Cargo Commands
You'll use these commands constantly. Here's what each does and when to reach for it:
cargo build
Compiles your project without running it. The output binary lands in target/debug/. Use this when you want to check that everything compiles but don't need to execute it.
cargo run
Compiles and then immediately runs the binary. This is your main development loop command. Arguments after -- are passed to your program: cargo run -- --port 3000.
cargo check
Runs the compiler's analysis without producing a binary. This is significantly faster than cargo build because it skips code generation. Use it to quickly check for errors while you're writing code.
cargo build --release
Compiles with optimizations. The output goes to target/release/. Much slower to compile, but the resulting binary is much faster. You'll use this for benchmarks and production builds in Chapter 25.
target/ directory can get large - it's where all compiled artifacts live. It's safe to delete anytime (cargo clean). Add it to your .gitignore - cargo new already does this for you.Exercise: Make It Yours
Before moving on, try these on your own to get comfortable with the workflow:
- Modify
main.rsto print your name:println!("Server by {your name}"); - Use
cargo checkto verify it compiles without running. - Introduce a deliberate error - remove a semicolon or misspell
println- and read the compiler's error message. Rust's error messages are famously helpful. Get used to reading them carefully. - Run
cargo buildand find the binary intarget/debug/. Run it directly:./target/debug/webserver
What's Next
You have a working Rust project with a running program. It doesn't do much yet - but the toolchain is in place and you know how to build, run, and check code.
In the next chapter, we'll cover the language fundamentals - variables, types, functions, and control flow - the building blocks you'll need before we start writing any networking code.