Skip to content

The Rust Toolchain

As a modern language, one of the major draws to Rust is its official toolchain. At its core the Rust toolchain includes the rustc compiler and a dependency manager/build system/wundertool called cargo. Rust is an ahead-of-time compiled language that supports most major modern platforms. Both the standard compiler and the build tool identify your host architecture to ensure that processes produce compatible binaries for your system. Rust identifies architectures as “triples” which consist of values in a [cpu_architecture-vendor-operating_system] format. For example, the triple for my Intel-based Mac is x86_64-apple-darwin. The compiler documentation contains a section on current platform support that is worth a look for the curious. The executables and libraries that rustc and cargo operations produce can run on any machine with the same triple regardless of whether Rust is installed. Compiling for different target triples involves a more advanced process called cross compilation which includes defining the target triple and an appropriate target toolchain. Cross compilation is not covered in this text. The core Rust toolchain also contains the Rust standard library, and optionally some quality of life tools like a linter called clippy and a code formatter called rustfmt. Rust makes installing and managing these elements easy with the rustup toolchain manager.

Toolchain Installation

This section covers the basics for what you need to get up and running with Rust using the rustup toolchain installer and manager.

Install Rustup

It’s possible to take on all sorts of custom installation configurations, but by far the easiest way (on UNIX-like systems) is to start with Rust’s toolchain manager rustup. Rust provides the following cURL command that fetches and runs a Bash script to install the toolchain manager rustup as well as rustc and cargo:

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

Installation Check

After the installation process completes you can verify by checking component versions. You’ll want to ensure that you have installed at least the compiler (rustc) and build system/package manager (cargo).

$ rustc --version
rustc 1.69.0 (84c898d65 2023-04-16)
$ cargo --version
cargo 1.69.0 (6e9a83356 2023-04-12)

More generally you can check which components are available with rustup component list and which components you have installed with rustup component list --installed.

$ rustup component list --installed
cargo-x86_64-apple-darwin
clippy-x86_64-apple-darwin
rust-analyzer-x86_64-apple-darwin
rust-docs-x86_64-apple-darwin
rust-src
rust-std-x86_64-apple-darwin
rustc-x86_64-apple-darwin
rustfmt-x86_64-apple-darwin

Write A Test Program

To make sure its all working as it should you can use the following steps to write, compile, and run a simple program:

  1. From the parent directory of your choice create and cd into a test directory.

    ~ $ mkdir test
    ~ $ cd test
  2. Create and open a Rust file, indicated by the .rs extension, in your preferred editor.

    ~/test $ touch main.rs
    ~/test $ nvim main.rs
  3. In the file save the following contents:

    fn main() {
    println!("Hello, world!");
    }
  4. From the same directory that your new test program is located in use the rustc tool to compile the code. This compilation step creates a new binary executable file. The executable does not have a file extension. Run the executable by simply typing ./ and the name of the executable.

    ~/test $ rustc main.rs
    ~/test $ ./main

If the system outputs the proper Hello, world text, congratulations, you’ve written and executed your first Rust program! Wild how similar this is to compiling and running C programs, right? Its almost like its… nevermind.

Next Steps

The rustc compiler is useful for simple, single source files, but as your projects grow in complexity, you will likely need more tooling. Specifically you’ll need a linker to support developing applications with more than one object file. Its also recommended to install a C/C++ compiler as many Rust dependencies are written in those languages and may require compilation. As of January 2025 rustup does not ship with a linker or a C/C++ compiler. On most UNIX-based systems, you can use LLVM’s Clang or GNU’s GCC, which ship with the lld and ld linkers respectively. On macOS, rustc and cargo look for the macOS-specific version of the ld linker by default so the easiest option on macOS is to install xcode-select. The OS uses this package (a ~1.2GB subset of the 40GB xcode command-line tools package) to install necessary elements and configure the Apple development environment.

To install the necessary tools on macOS, run:

xcode-select --install

In contrast to the test program detailed on this page, most Rust development in the real world uses cargo. The cargo tool handles project creation/setup, dependency management, compilation/building, testing, formatting, and much more. Cargo is a very large tool, so it’s covered in a dedicated section later on.

Managing Toolchain Versions

This section contains some common operations for managing your shiny new Rust toolchain. For more details see the official rustup documentation.

Check Version

Run the rustup toolchain list command to see which versions you have installed. Add the -v / --verbose option to see where they’re installed.

$ rustup toolchain list -v
stable-x86_64-apple-darwin /Users/me/.rustup/toolchains/stable-x86_64-apple-darwin
1.69.0-x86_64-apple-darwin (default) /Users/me/.rustup/toolchains/1.69.0-x86_64-apple-darwin

Alternatively you can run show (with or without -v) to show all installed toolchains which adds information that includes versions and the toolchain channels. Channels are essentially just labels that group timed releases into “stable”, “beta”, and “nightly” categories. The show command also indicates the active toolchain. The active toolchain is an indicator for which toolchain is currently targeted, for example, when invoking the show command. Rustup contains the notion of a default setting to name a toolchain that Rust uses when no command option is specified. This example indicates that both the active and default version is set to the “stable” channel.

$ rustup show -v
Default host: x86_64-apple-darwin
rustup home: /Users/p5chmitz/.rustup
installed toolchains
--------------------
stable-x86_64-apple-darwin (default)
rustc 1.83.0 (90b35a623 2024-11-26)
nightly-x86_64-apple-darwin
rustc 1.86.0-nightly (243d2ca4d 2025-01-06)
1.73.0-x86_64-apple-darwin
rustc 1.73.0 (cc66ad468 2023-10-03)
active toolchain
----------------
stable-x86_64-apple-darwin (default)
rustc 1.83.0 (90b35a623 2024-11-26)

Update Version

Use the update command to update toolchains with the rustup update [OPTIONS] [toolchain] argument pattern. If you pass no [toolchain] arguments (as channel or sem. ver.) the utility updates all installed toolchain channels to their latest versions. This does not touch any of the specific semantic versioned toolchains installed. To update semantic versions specify those specifically. Use the rustup update --help command for a list of options. After updating, use the toolchain list or toolchain show command to see updates.

$ rustup update // Updates all channels to the latest versions
OR
$ rustup update 1.73 // Updates v1.73 to the latest version as 1.73.x

Check/Update Default Version

Without any arguments, the rustup default command prints the current global default toolchain version. This is the version that the toolchain uses when you do not supply a channel/version to an operation, for example a cargo operation that invokes the compiler.

$ rustup default
1.73.0-x86_64-apple-darwin (default)
$ rustup default 1.69.0

If you add an identifier to the default command you can update the default toolchain version. This example shows how to set the default toolchain to the stable channel.

$ rustup default stable
info: using existing install for 'stable-x86_64-apple-darwin'
info: default toolchain set to 'stable-x86_64-apple-darwin'
stable-x86_64-apple-darwin unchanged - rustc 1.79.0 (129f3b996 2024-06-10)

Run the toolchain list or show command to ensure that changes took.

Override Active Version

It may be helpful to temporarily switch active versions/channels to use certain toolchain features. For example Miri is an undefined behavior detector that is only available on the nightly channel. To switch active channels use the rustup run [channel] [args] command pattern. This example runs a Miri test without changing the default toolchain.

rustup run nightly cargo miri test

Depending on what you’re doing it may be easier to either update your default toolchain or name the channel directly through a cargo operation using the + operator. This example also runs Miri through the nightly channel but with a cleaner argument pattern:

cargo +nightly miri test

Uninstall a Version

To uninstall a version/channel, use the toolchain uninstall command to specify which version you want to uninstall. Note that if you uninstall a default version, it will not update the default version, which will need to be updated separately.

$ rustup toolchain uninstall 1.73.0
info: uninstalling toolchain '1.73.0-x86_64-apple-darwin'
info: toolchain '1.73.0-x86_64-apple-darwin' uninstalled

Ununstall Rust

To uninstall Rust :( use the self uninstall command.

rustup self uninstall