Skip to main content
← All Articles Β· Β· 9 min read

Best Rust Developer Tools 2026: cargo, clippy, rustfmt & More

Best Rust developer tools 2026: Cargo ecosystem, clippy linting, rustfmt formatting, rust-analyzer LSP, cargo-watch, cargo-flamegraph, miri, and essential productivity crates.

Rustdeveloper toolscargoclippyrustfmtrust-analyzer

Rust’s tooling ecosystem has matured enormously since its 1.0 release. In 2026, the combination of first-party tools like cargo, clippy, and rustfmt plus a rich ecosystem of community extensions makes Rust one of the best-equipped languages for developer productivity. This guide covers every tool you need to write, lint, format, profile, and secure Rust code efficiently.

The Cargo Command Essentials

cargo is Rust’s all-in-one build tool, package manager, and task runner. Mastering its subcommands saves significant daily friction.

# Build and run
cargo build                  # debug build
cargo build --release        # optimized release build
cargo run -- --arg value     # build + run with arguments
cargo run --release          # release build + run

# Testing
cargo test                   # run all tests
cargo test -- --nocapture    # show stdout from tests
cargo test integration_      # run tests matching a pattern
cargo bench                  # run benchmark tests (requires #[bench])

# Documentation
cargo doc --open             # build and open HTML docs
cargo doc --no-deps          # only doc your crate, skip deps

# Dependency management
cargo update                 # update Cargo.lock
cargo tree                   # visualize dependency tree
cargo tree -d                # show duplicate dependencies
cargo add serde --features derive  # add dep with features
cargo remove serde           # remove a dependency

Cargo.toml Feature Flags

[features]
default = ["std"]
std = []
async = ["tokio"]
full = ["std", "async", "serde"]

[dependencies]
serde = { version = "1", optional = true }
tokio = { version = "1", features = ["full"], optional = true }

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true

Clippy: The Lint Machine

clippy is Rust’s official linter with 700+ lint rules. It catches logical bugs, performance issues, and idiomatic improvements that the compiler misses.

cargo clippy                        # run with default lints
cargo clippy -- -D warnings         # treat warnings as errors (CI mode)
cargo clippy --all-targets          # lint tests and examples too
cargo clippy --fix                  # auto-apply suggestions

Configuring Clippy Levels

// At the crate level (lib.rs or main.rs)
#![deny(clippy::all)]              // all default lints as errors
#![warn(clippy::pedantic)]         // extra pedantic lints as warnings
#![allow(clippy::module_name_repetitions)]  // suppress specific lints

// At the function level
#[allow(clippy::too_many_arguments)]
fn complex_setup(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32) -> i32 {
    a + b + c + d + e + f + g
}

Common Clippy Catches

// clippy::redundant_clone β€” unnecessary clone
let s = String::from("hello");
let _t = s.clone();  // clippy warns: s is moved later anyway

// clippy::map_unwrap_or β€” use unwrap_or_else
let x: Option<i32> = Some(5);
// Bad:
let _ = x.map(|v| v * 2).unwrap_or(0);
// Better (clippy suggestion):
let _ = x.map_or(0, |v| v * 2);

// clippy::needless_collect β€” don't collect just to iterate
let v: Vec<i32> = vec![1, 2, 3];
// Bad:
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
doubled.iter().for_each(|x| println!("{x}"));
// Better:
v.iter().map(|x| x * 2).for_each(|x| println!("{x}"));

rustfmt: Consistent Code Formatting

rustfmt enforces a consistent code style. Configure it via rustfmt.toml in your project root.

cargo fmt                    # format all files
cargo fmt -- --check         # exit non-zero if changes needed (CI)
cargo fmt --all              # format entire workspace

rustfmt.toml Configuration

edition = "2021"
max_width = 100
tab_spaces = 4
use_small_heuristics = "Default"
imports_granularity = "Crate"   # group imports by crate
group_imports = "StdExternalCrate"  # std, then external, then local
wrap_comments = true
format_code_in_doc_comments = true

rust-analyzer: The LSP Server

rust-analyzer is the official Rust Language Server. It powers autocomplete, go-to-definition, inline type hints, and code actions in every major editor.

VS Code setup:

// .vscode/settings.json
{
  "rust-analyzer.checkOnSave.command": "clippy",
  "rust-analyzer.inlayHints.parameterHints.enable": true,
  "rust-analyzer.inlayHints.typeHints.enable": true,
  "rust-analyzer.cargo.features": "all",
  "rust-analyzer.procMacro.enable": true
}

Key features:

  • Inline type hints for inferred types
  • Expand macro invocations inline
  • Smart completions for trait implementations
  • Rename refactoring across the workspace
  • Show documentation on hover
  • β€œFill struct fields” code action

cargo-watch: Auto-Recompile on Change

cargo install cargo-watch

cargo watch -x run              # re-run on any file change
cargo watch -x test             # re-run tests
cargo watch -x "clippy -- -D warnings"  # continuous linting
cargo watch -s "echo done" -x build     # run shell command after build

This is essential for tight feedback loops, especially when working on CLI tools or servers.


cargo-flamegraph: Profiling Made Easy

cargo install flamegraph
# On Linux, may need: sudo apt install linux-perf

cargo flamegraph --bin my_app   # generates flamegraph.svg
cargo flamegraph --test my_test -- test_name

The output is an SVG flamegraph showing where CPU time is spent. No complex perf setup needed.


cargo-expand: Debug Macros

Macros in Rust can be opaque. cargo-expand shows the expanded output of any macro invocation.

cargo install cargo-expand
cargo expand                    # expand entire crate
cargo expand my_module          # expand specific module
cargo expand --test my_test     # expand test module
// Before expansion:
#[derive(Debug, Clone, serde::Serialize)]
struct User {
    name: String,
    age: u32,
}

// cargo expand shows the generated impl blocks for Debug, Clone, Serialize

miri: Undefined Behavior Detection

miri is an interpreter for Rust’s MIR (Mid-level IR) that detects undefined behavior, use-after-free, data races, and more.

rustup component add miri
cargo miri test              # run tests under miri
cargo miri run               # run binary under miri
// miri catches this:
let v: Vec<i32> = vec![1, 2, 3];
let ptr = v.as_ptr();
drop(v);
// unsafe { *ptr }  // miri: use-after-free detected!

Miri is slower than normal execution but invaluable for verifying unsafe blocks.


cargo-audit: Security Vulnerability Scanning

cargo install cargo-audit
cargo audit                  # check Cargo.lock against RustSec advisory DB
cargo audit fix              # upgrade vulnerable deps
# Example output:
Crate:    openssl
Version:  0.10.48
Title:    Use after free in CMS Signing
Date:     2023-05-30
ID:       RUSTSEC-2023-0044
URL:      https://rustsec.org/advisories/RUSTSEC-2023-0044
Severity: 7.5 (high)

Integrate into CI with cargo audit --deny warnings to block builds with known vulnerabilities.


Essential Developer Crates

CratePurposeExample Use
anyhowApp-level error handlingfn main() -> anyhow::Result<()>
thiserrorLibrary error types#[derive(thiserror::Error)]
tracingStructured async-aware loggingtracing::info!(user_id, "login")
tokioAsync runtime#[tokio::main]
serdeSerialization/deserialization#[derive(Serialize, Deserialize)]
rayonData parallelism.par_iter().map(...)
clapCLI argument parsing#[derive(Parser)]
reqwestHTTP clientreqwest::get(url).await?
// anyhow for applications β€” context chaining
use anyhow::{Context, Result};

fn read_config(path: &str) -> Result<Config> {
    let content = std::fs::read_to_string(path)
        .with_context(|| format!("Failed to read config at {path}"))?;
    let config: Config = toml::from_str(&content)
        .context("Failed to parse config as TOML")?;
    Ok(config)
}

// thiserror for libraries β€” typed errors
use thiserror::Error;

#[derive(Error, Debug)]
pub enum DatabaseError {
    #[error("connection failed: {0}")]
    Connection(#[from] std::io::Error),
    #[error("query error: {message}")]
    Query { message: String },
    #[error("row not found for id {id}")]
    NotFound { id: u64 },
}

Tool Summary Table

ToolInstallPrimary Use
cargoBuilt-inBuild, test, manage deps
clippyrustup component add clippyLinting
rustfmtrustup component add rustfmtFormatting
rust-analyzerVia editor extensionLSP / IDE features
cargo-watchcargo install cargo-watchAuto-recompile
cargo-flamegraphcargo install flamegraphCPU profiling
cargo-expandcargo install cargo-expandMacro debugging
mirirustup component add miriUB detection
cargo-auditcargo install cargo-auditSecurity scanning
cargo-nextestcargo install cargo-nextestFaster test runner

# .github/workflows/ci.yml
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt
      - run: cargo fmt -- --check
      - run: cargo clippy --all-targets -- -D warnings
      - run: cargo test --all-features
      - run: cargo audit

With this toolchain, Rust development in 2026 is fast, safe, and well-observable β€” from the first cargo new to production deployment.

Free Download

50 CLI Commands That Save Hours Every Week

The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.

  • Git mastery (10 cmds)
  • File & search wizardry
  • Docker & DevOps tricks
  • Process & network tools
  • Productivity boosters
  • macOS & Linux install guide

No spam. 1 email/week max. Unsubscribe anytime.

Found this guide useful? Check out our free developer tools.