Getting Started with Rust: Installation, Cargo, and Writing Your First Program Tutorial

Getting Started with Rust

I remember the first time I heard about Rust — everyone kept saying the same three things: it’s fast, it’s memory-safe without a garbage collector, and it has a notoriously strict compiler. What nobody told me was how smooth the actual getting-started experience would be. In this article, I’ll walk you through installing Rust, understanding Cargo (Rust’s build tool and package manager), and writing and running your first real program.

Why Learn Rust in the First Place

Before diving into installation, it’s worth understanding what makes Rust worth learning. Rust guarantees memory safety — no null pointer dereferences, no data races, no dangling pointers — and it does this entirely at compile time, without a garbage collector slowing things down at runtime. This makes Rust a serious choice for systems programming, WebAssembly, embedded devices, command-line tools, and increasingly, backend web services. The tradeoff is a steeper learning curve up front, but the payoff is code that’s both fast and remarkably robust.

Installing Rust

The official and recommended way to install Rust is through rustup, a toolchain installer and version manager maintained by the Rust project itself.

On Linux or macOS

Open a terminal and run:

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

This downloads and runs the rustup installation script. It will ask you a few questions and, by default, install the stable toolchain along with cargo, rustc, and rustup itself.

On Windows

Download and run rustup-init.exe from the official Rust website (rust-lang.org/tools/install). It will prompt you to install the Microsoft C++ Build Tools if they aren’t already present, since Rust on Windows relies on the MSVC linker by default.

Verifying the Installation

Once installation finishes, restart your terminal (or source your shell profile) and check the versions:

rustc --version
cargo --version

Expected output looks something like this (versions will vary depending on when you install):

rustc 1.82.0 (f6e511eec 2024-10-15)
cargo 1.82.0 (8f40fc59f 2024-08-21)

If both commands return version numbers, the installation succeeded.

Updating and Managing Toolchains

One thing I really appreciate about rustup is how easy it makes managing Rust versions:

rustup update          # update to the latest stable release
rustup show             # show installed toolchains
rustup default stable   # set the default toolchain

You can also install and switch between stable, beta, and nightly toolchains, which matters if you ever need access to experimental, unstable features gated behind nightly-only flags.

Understanding Cargo

Cargo is Rust’s build system and package manager, and honestly, it’s one of the biggest reasons Rust feels so pleasant to work with compared to some other systems languages. Cargo handles:

  • Creating new projects with a standard structure.
  • Compiling your code (cargo build).
  • Running your code (cargo run).
  • Managing dependencies (crates) from crates.io.
  • Running tests (cargo test).
  • Formatting code (cargo fmt).
  • Linting code (cargo clippy).
  • Generating documentation (cargo doc).
  • Publishing packages to the crates.io registry (cargo publish).

Creating a New Project

Let’s create a real project instead of just a single file:

cargo new hello_rust

Output:

     Created binary (application) `hello_rust` package

This generates a directory structure like this:

hello_rust/
├── Cargo.toml
├── .gitignore
└── src/
    └── main.rs

Cargo.toml is the project’s manifest file — it declares metadata about your package and lists its dependencies:

[package]
name = "hello_rust"
version = "0.1.0"
edition = "2021"
[dependencies]

src/main.rs is where your actual code lives, and Cargo has already scaffolded a working “Hello, world!” program for you:

fn main() {
    println!("Hello, world!");
}

Building and Running

Navigate into the project directory and run it:

cd hello_rust
cargo run

Output:

   Compiling hello_rust v0.1.0 (/path/to/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.45s
     Running `target/debug/hello_rust`
Hello, world!

cargo run compiles your project (if it hasn’t changed since the last build) and immediately executes the resulting binary. If you only want to compile without running, use cargo build. And when you’re ready to build a fully optimized binary for production or distribution, use:

cargo build --release

This produces a binary in target/release/ instead of target/debug/, with optimizations enabled and debug assertions (like overflow checks) turned off, resulting in noticeably faster execution.

Writing Your First Real Program

Let’s go beyond “Hello, world!” and write something a bit more meaningful — a small program that takes a name and greets the user, while introducing variables, a function, and basic control flow.

fn main() {
    let name = "Rustacean";
    greet(name);

    let numbers = vec![4, 8, 15, 16, 23, 42];
    let total: i32 = numbers.iter().sum();

    println!("The sum of the numbers is: {}", total);

    if total > 100 {
        println!("That's a big total!");
    } else {
        println!("That's a modest total.");
    }
}

fn greet(name: &str) {
    println!("Hello, {}! Welcome to Rust.", name);
}

Output:

Hello, Rustacean! Welcome to Rust.
The sum of the numbers is: 108
That's a big total!

This tiny program already touches on several important Rust concepts: immutable variable bindings, function definitions with typed parameters (&str is a string slice reference), a Vec<i32> collection, an iterator method (.iter().sum()), and a basic conditional expression.

Adding a Dependency (Your First Crate)

One of Cargo’s most powerful features is how effortlessly it pulls in external libraries, called “crates.” Let’s add the popular rand crate for generating random numbers.

Open Cargo.toml and add it under [dependencies]:

[dependencies]
rand = "0.8"

Then update src/main.rs:

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    let number: u32 = rng.gen_range(1..=100);
    println!("Random number between 1 and 100: {}", number);
}

Run it:

cargo run

Cargo will automatically download, compile, and link the rand crate before running your program:

    Updating crates.io index
  Downloaded rand v0.8.5
   Compiling rand v0.8.5
   Compiling hello_rust v0.1.0 (/path/to/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 2.31s
     Running `target/debug/hello_rust`
Random number between 1 and 100: 57

Cargo also creates a Cargo.lock file the first time you build with dependencies. This file pins the exact versions of every crate (and their transitive dependencies) used in the build, ensuring reproducible builds across machines and over time.

Project Structure for Larger Programs

As your project grows beyond a single file, Cargo’s conventions keep things organized:

my_project/
├── Cargo.toml
├── Cargo.lock
├── src/
│   ├── main.rs
│   ├── lib.rs
│   └── modules/
│       └── utils.rs
├── tests/
│   └── integration_test.rs
└── target/
  • src/main.rs is the entry point for a binary crate.
  • src/lib.rs is the entry point for a library crate, if your project also exposes reusable code.
  • tests/ holds integration tests, which Cargo automatically discovers and runs with cargo test.
  • target/ is where all compiled artifacts go — this directory is auto-generated and typically excluded from version control via .gitignore.

Essential Cargo Commands to Remember

cargo new project_name     # create a new binary project
cargo new --lib lib_name    # create a new library project
cargo build                 # compile the project
cargo build --release       # compile with optimizations
cargo run                   # compile and run
cargo check                 # type-check without producing a binary (fast feedback loop)
cargo test                  # run tests
cargo fmt                   # auto-format code according to Rust style conventions
cargo clippy                # run the linter for idiomatic suggestions
cargo doc --open            # generate and open documentation locally

I use cargo check constantly while writing code — it’s significantly faster than a full cargo build since it skips code generation and only checks that the code compiles correctly, which is perfect for a tight feedback loop while editing.

Setting Up an Editor

While not strictly required, I strongly recommend using an editor with Rust-specific tooling. Visual Studio Code with the rust-analyzer extension gives you real-time type checking, inline error messages, autocomplete, and go-to-definition support, which makes learning Rust’s type system dramatically easier since you get instant feedback as you type.

Common Mistakes Beginners Make

  • Skipping rustup and installing Rust through a system package manager: This often results in an outdated compiler version and makes it harder to manage multiple toolchains later.
  • Ignoring Cargo.lock in version control for binaries: For applications (not libraries), it’s recommended to commit Cargo.lock to ensure everyone builds with identical dependency versions.
  • Editing files inside target/: This directory is entirely generated by Cargo and gets wiped on cargo clean — never store your own code there.
  • Forgetting to run cargo build --release for performance testing: Debug builds include overflow checks and skip optimizations, so they can be significantly slower than release builds — don’t judge Rust’s speed based on debug-mode benchmarks.

Best Practices for Getting Started

  1. Always install Rust via rustup rather than a system package manager, so you can easily manage toolchain versions.
  2. Use cargo new for every project, even small experiments — it sets up sensible defaults from day one.
  3. Run cargo check frequently while coding for fast feedback, and save cargo build/cargo run for when you actually need to execute the program.
  4. Install rust-analyzer in your editor early — it dramatically shortens the learning curve.
  5. Get comfortable reading compiler errors closely. Rust’s error messages are famously detailed and often tell you exactly how to fix the problem.

Troubleshooting and FAQs

Q: cargo or rustc command not found after installation — what do I do? Make sure ~/.cargo/bin (or the equivalent path on Windows) is added to your system’s PATH environment variable, and restart your terminal session after installation.

Q: Do I need to install a C++ compiler to use Rust? On Windows, yes — Rust’s default toolchain uses the MSVC linker, so you’ll need the Microsoft C++ Build Tools. On Linux and macOS, a basic C toolchain (gcc/clang) is usually already present or easily installed via your package manager.

Q: What’s the difference between cargo build and cargo run? cargo build only compiles the project, producing a binary in the target directory. cargo run compiles (if needed) and then immediately executes that binary.

Q: Why is my release build so much faster than my debug build? Debug builds include overflow checks, less aggressive optimization, and additional debug symbols for easier troubleshooting. Release builds strip much of this out and apply full compiler optimizations, at the cost of longer compile times.

Q: How do I remove all build artifacts and start fresh? Run cargo clean, which deletes the target directory entirely, forcing a full rebuild on the next cargo build or cargo run.

Summary

Getting started with Rust is far less intimidating than its reputation suggests, mostly thanks to rustup and Cargo. rustup gives you a clean, version-managed installation process, while Cargo handles everything from project scaffolding to dependency management to testing and documentation, all through a consistent command-line interface. Once you’ve installed the toolchain, created your first project, and run a program that pulls in an external crate, you already understand the core workflow you’ll use for every Rust project going forward, no matter how large it grows.

References

  • Official Rust Installation Guide: https://www.rust-lang.org/tools/install
  • The Rust Programming Language Book: https://doc.rust-lang.org/book/
  • The Cargo Book (official documentation): https://doc.rust-lang.org/cargo/
  • Crates.io, the official Rust package registry: https://crates.io/
Total
0
Shares

Leave a Reply

Previous Post
Connecting Python to SQL Server

Connecting Python to SQL Server: Complete Database Integration and Query Execution Guide

Next Post
Printing on the Terminal in Rust

Printing on the Terminal in Rust: println!, format!, and Standard Output Macros Explained

Related Posts