Pre-commit & Editor Setup
Local tooling catches fmt and clippy issues before CI. rust-analyzer plus format-on-save and optional pre-commit hooks keep feedback instant.
Recipe
// .vscode/settings.json
{
"editor.formatOnSave": true,
"rust-analyzer.check.command": "clippy",
"rust-analyzer.rustfmt.extraArgs": ["+nightly"]
}# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: cargo-fmt
entry: cargo fmt --all -- --check
language: system
pass_filenames: false
- id: cargo-clippy
entry: cargo clippy --workspace --all-targets -- -D warnings
language: system
pass_filenames: falseWhen to reach for this: Onboarding developers and reducing CI churn from style-only failures.
Working Example
# rust-toolchain.toml
[toolchain]
channel = "1.97.0"
components = ["rustfmt", "clippy"]rustup component add rustfmt clippy
pre-commit installWhat this demonstrates:
- Pinned toolchain matches CI Rust 1.97.0
- rust-analyzer uses clippy for inline diagnostics
- pre-commit runs same checks as CI subset
componentsensures fmt/clippy available offline
Deep Dive
rust-analyzer Essentials
| Setting | Effect |
|---|---|
check.command = "clippy" | Inline clippy hints |
cargo.features | Active feature set for analysis |
linkedProjects | Workspace member selection |
inlayHints | Type/lifetime hints (optional) |
Hook Strategies
- pre-commit - fast fmt + clippy on staged Rust
- pre-push - full
cargo test(slower) - mise/direnv - auto
rustuptoolchain on cd
Gotchas
- rust-analyzer wrong toolchain - spurious errors. Fix:
rust-toolchain.tomlin repo root; reload RA. - Format on save without rustfmt component - silent failure. Fix:
rustup component add rustfmt. - Clippy hook on every commit - slow on large workspaces. Fix: scope to changed crates with
cargo clippy -pscripts. - Nightly fmt in stable project - inconsistent formatting. Fix: use stable 1.97.0 rustfmt only unless team chooses nightly.
- Skipping hooks with --no-verify - defeats purpose. Fix: culture + CI backstop; allow only emergencies.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
lefthook / husky | Polyglot repos | Simple Rust-only |
| CI only | Solo hacker prototype | Teams with PR volume |
cargo watch -x check | Long coding sessions | Replacing fmt on save |
FAQs
VS Code vs Cursor setup?
Same rust-analyzer extension and settings.json keys.
How select workspace crate in RA?
rust-analyzer.linkedProjects or Cargo: Open Cargo.toml picks crate context.
pre-commit on Windows?
language: system hooks need cargo on PATH; use same rust-toolchain.toml.
Format imports on save?
rustfmt handles imports; enable formatOnSave only.
Clippy fix on save?
Not default; run cargo clippy --fix manually with review.
How share settings?
Commit .vscode/settings.json with team defaults; optional personal overrides gitignored.
rust-analyzer slow?
Exclude target/ from file watcher; use cargo clean if metadata corrupt; split large workspace.
Mise vs rustup?
Both pin toolchain; rust-toolchain.toml is canonical for rustup; mise can read it.
Hook only staged files?
Rust fmt/clippy are crate-wide; full workspace check is safer for type errors across files.
EditorConfig with rustfmt?
EditorConfig for non-Rust files; rustfmt.toml owns Rust formatting.
Related
- rustfmt - formatting rules
- Clippy - lint diagnostics
- Linting in CI - server-side gates
- Toolchain Setup Checklist - onboarding
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.