23.2 The Cargo Command-Line Interface (CLI)
Cargo is primarily used via the command line. You can verify your installation and see available commands:
cargo --version
cargo --help
Below are some of the most frequently used Cargo commands.
23.2.1 cargo new
and cargo init
These commands initialize a new Rust project (package).
cargo new <project_name>
: Creates a new directory named<project_name>
containing a minimalCargo.toml
file and asrc/
directory with a basicmain.rs
(for a binary package/crate) orlib.rs
(for a library package/crate). Crucially, it also initializes a Git repository by default (complete with a.gitignore
file), as most Rust projects are managed with Git. This practice facilitates collaboration and version tracking, often on platforms like GitHub.cargo init [<path>]
: Initializes a Cargo package structure within an existing directory. If<path>
is omitted, it uses the current directory. It will also create a.gitignore
file if a Git repository is not already present but will not initialize a new Git repository if one doesn’t exist.
Use the --lib
flag to create a library package instead of the default binary (application) package:
# Create a new binary application package named 'hello_world'
cargo new hello_world
# Create a new library package named 'my_utils'
cargo new my_utils --lib
# Initialize the current directory as a Cargo package (defaults to binary)
cargo init
# Initialize './existing_lib_dir' as a library package
cargo init --lib ./existing_lib_dir
23.2.2 cargo build
and cargo run
These commands compile and execute your code.
cargo build
: Compiles the current package, including its crates. By default, it builds in debug mode, which prioritizes faster compilation times over runtime performance and includes debugging information. Output artifacts are placed in thetarget/debug/
directory.cargo run
: Compiles the package (if necessary) and then executes the resulting binary (only applicable to binary packages/crates). Also defaults to debug mode.
# Build the package in debug mode
cargo build
# Build and run the package's default binary in debug mode
cargo run
Release Mode
For production builds or performance testing, use release mode. This enables more aggressive compiler optimizations, resulting in slower compilation but faster runtime performance and smaller binaries. Debug information is typically omitted.
# Build with release optimizations
cargo build --release
# Build and run in release mode
cargo run --release
Release artifacts are placed in a separate target/release/
directory. Incremental compilation behaves differently in release mode, as discussed in Section 23.5.1.
23.2.3 cargo check
This command quickly checks your code for compilation errors without generating any executable code. It performs parsing, type checking, and borrow checking on the crates within your package.
cargo check
cargo check
is significantly faster than cargo build
, especially for larger projects, because it skips the code generation (LLVM) phase. It’s useful for getting rapid feedback during development. It also benefits from incremental checking.
23.2.4 cargo clean
Removes the target/
directory, deleting all compiled artifacts (executables, libraries, intermediate files) for the current package.
cargo clean
This is useful when you suspect build issues might be related to stale artifacts, need to force a full rebuild of the package’s crates, or want to free up disk space.
23.2.5 cargo add
, cargo remove
, cargo upgrade
These commands manage dependencies listed in your Cargo.toml
. They operate on dependency packages.
cargo add <package_name>
: Adds a dependency on the latest compatible version of the package<package_name>
from Crates.io to yourCargo.toml
.cargo remove <package_name>
: Removes a dependency package fromCargo.toml
.cargo upgrade
: Updates dependencies inCargo.toml
to their latest compatible versions according to SemVer rules. (Note: This command is provided by the externalcargo-edit
tool, see Section 23.2.10).
# Add the 'serde' package as a dependency
cargo add serde
# Add 'rand' as a development-only dependency package (for tests, examples)
cargo add rand --dev
# Add a specific version of the 'serde' package with a feature enabled
cargo add serde --version "1.0.150" --features "derive"
# Remove the 'rand' package
cargo remove rand
These commands modify Cargo.toml
and automatically update Cargo.lock
(see Section 23.4.3). Before Rust 1.62, cargo add
and remove
were part of the external cargo-edit
tool. They are now built-in.
23.2.6 cargo fmt
Formats your package’s Rust code according to the community-standard style guidelines using the rustfmt
tool.
cargo fmt
Running cargo fmt
regularly helps maintain a consistent code style across the project’s crates, reducing cognitive load and preventing style-related noise in code reviews and version control history.
23.2.7 cargo clippy
Runs Clippy, Rust’s official collection of lints. Clippy provides suggestions to improve code correctness, performance, style, and idiomatic usage within your package’s crates.
cargo clippy
Clippy often catches potential bugs or suggests better ways to express logic. It’s highly recommended to run clippy
as part of your development workflow and CI process.
23.2.8 cargo fix
Automatically applies suggestions made by the Rust compiler (rustc
) or Clippy to fix warnings or simple errors in your package’s code.
# Apply compiler suggestions
cargo fix
# Apply suggestions, even with uncommitted changes (use with caution)
# (This assumes changes are staged or you accept working with a dirty tree)
cargo fix --allow-dirty
Always review the changes made by cargo fix
before committing them to your version control system.
23.2.9 cargo doc
Generates HTML documentation for your package and its dependencies based on documentation comments in the source code of its crates.
# Generate documentation (output in target/doc/)
cargo doc
# Generate documentation and open the main page in a browser
cargo doc --open
# Generate docs only for your package's own crates (not dependencies)
cargo doc --no-deps
Documentation generation is covered further in Section 23.8.
23.2.10 Extending Cargo: cargo install
and External Tools
Cargo can be extended with custom subcommands. You can install additional tools distributed as binary packages using cargo install
.
cargo install <package_name>
: Downloads and installs a binary package globally (typically in~/.cargo/bin/
). Cargo builds the binary crate within the package and places the resulting executable. Ensure this directory is in your system’sPATH
.- External Subcommands: If you install a binary named
cargo-foo
, you can invoke it ascargo foo
.
Examples of useful tools installable via cargo install
:
cargo-edit
: Providescargo upgrade
,cargo set-version
, and other convenient commands for managingCargo.toml
dependencies.cargo-outdated
: Checks for dependency packages that have newer versions available on Crates.io than specified inCargo.lock
.cargo-audit
: AuditsCargo.lock
for dependency packages with known security vulnerabilities reported to the RustSec Advisory Database.cargo-expand
: Shows the result of macro expansion within your code.cargo-miri
: Runs your code (includingunsafe
code) in an interpreter (Miri) to detect certain kinds of Undefined Behavior (UB). Requires installing the Miri component:rustup component add miri
.
# Install the cargo-edit package (and its binary crate)
cargo install cargo-edit
# Now you can use 'cargo upgrade'
cargo upgrade
# Install Miri and run
rustup component add miri
cargo miri run