A single native Rust binary for format, lint, affected-project detection, and lockfile restore. It does its own filesystem + XML discovery and text-preserving transforms, so it starts in milliseconds and beats the official tools by 1–2 orders of magnitude.
No .NET runtime needed to run it — the one exception is lint --deep, which shells to the SDK's real Roslyn analyzers.
# .NET global tool dotnet tool install -g RDLL.dotnet-fast # npm — for husky / lint-staged / JS monorepos npm i -D @rdll/dotnet-fast # from source → target/release/dotnet-fast cargo build --release
First run — the bare invocation is the gate, --fix repairs:
dotnet-fast path\to\App.sln # == lint: report findings, exit 1 if any (the CI gate) dotnet-fast lint --fix path\to\App.sln # apply every safe fix in one pass dotnet-fast hooks install # wire a pre-commit hook (lint --fix --staged)
dotnet-fast adapts its output to who is reading it. When it detects an AI/agent
shell — Claude Code, Cursor, or anything that sets AI_AGENT / DOTNET_FAST_AGENT=1
— it automatically switches to terse, low-token output. No flag needed.
Terse, low-token; ends with the exact fix: command. ~97% fewer characters — so an agent spends tokens deciding, not reading.
# auto in an agent shell
10 fixable, 1 manual · 1 file
fix: dotnet-fast lint --fix App.sln
manual:
src/C.cs:5:25 DF0001 ...
Plain text + machine formats. Exit-code-driven; SARIF / JSON / matrix feed code-scanning & matrix fan-out.
dotnet-fast lint --ci --sarif r.sarif dotnet-fast affected --ci --format matrix dotnet-fast update --audit --min-age 3 dotnet-fast doctor --strict
Rich, verbose report — TTY colors, per-rule tally. The default at a human terminal; force it with --human.
dotnet-fast lint App.sln --human dotnet-fast lint App.sln -v detailed dotnet-fast lint App.sln --summary dotnet-fast lint App.sln --deep
GitHub Copilot: the editor extension never shells out to the CLI, and the coding agent runs in
plain GitHub Actions (indistinguishable from CI), so it is not auto-detected — set
DOTNET_FAST_AGENT=1 in that workflow to opt in.
lint is the umbrella verb: bare = the gate, --fix = apply, --affected/--from/--ci = scope.
| Command | What it does |
|---|---|
dotnet-fast lint | Verify & report formatting + lint findings (whitespace, style, analyzer, 148 native CST rules · SARIF) — the CI gate, writes nothing, exits non-zero on any finding. --baseline fails only on new findings; --deep adds the project's real Roslyn analyzers. |
dotnet-fast lint --fix | Apply all safe fixes in one pass. Scope with --affected, --from/--to, --ci, or --staged (pre-commit, re-stages fixes). |
dotnet-fast affected | DotNetAffected-style detection of which projects a Git change impacts. --format matrix emits a CI job-matrix; --tests-only narrows to affected test projects. |
dotnet-fast restore | Lockfile-driven NuGet restore (UV-inspired): verify the cache + hydrate missing packages in parallel, skipping MSBuild. --verify-only is an instant CI no-op check; --offline is hermetic. |
dotnet-fast update | Report (or --apply) available package updates. --min-age is a supply-chain cooldown; --audit flags known-vulnerable (OSV) versions and gates CI. |
dotnet-fast sbom | CycloneDX 1.5 or SPDX 2.3 SBOM straight from packages.lock.json — no MSBuild, no build, no network. |
dotnet-fast doctor | Build-free workspace health scan (duplicate/orphaned references, CPM & version smells, inconsistent locks). --json / --sarif / --strict. |
dotnet-fast hooks install | Write managed pre-commit / pre-push Git hooks running lint --fix --staged — no husky/lint-staged needed. |
dotnet-fast editorconfig | explain <file> traces the resolved config chain; init infers a .editorconfig from the existing sources. |
Lint & fix
dotnet-fast lint App.sln --affected # only files this branch changed dotnet-fast lint --fix App.sln --staged # pre-commit: staged files, re-stage fixes dotnet-fast lint App.sln --baseline g.json # fail only on NEW findings
Affected (CI-aware)
dotnet-fast affected --ci --format json dotnet-fast affected --pr-base develop # gitflow PR dotnet-fast affected --push # vs previous commit
Exit codes
0 | clean |
1 | findings present (lint / bare dotnet-fast) |
2 | dotnet format-compat verify/apply failure |
3 | restore --verify-only found packages missing from the cache |
4 | restore --no-fallback/--offline precondition, or update found no lock |
166 | affected ran fine but nothing is affected (skip downstream) |
Verified-safe path: SDK-style C# workspaces covered by the parity tests — an 80-file differential
corpus at 100% byte parity with real dotnet format, and 91 of the SDK's 121
IDExxxx rules supported (25 out-of-scope/semantic, 5 deferred).