dotnet-fast

Fast .NET tooling,
without MSBuild or Roslyn

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.

292× startup format check 16–28× affected ~105× restore --verify-only 148 native lint rules 100% byte-parity corpus

InstallOne binary, three ways

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)

Output modesAI-agent output is the default in agent shells

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.

🤖 AI agent default

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 ...

🏗️ CI

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

🔍 Local / debug

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.

CommandsOne CLI, a few obvious verbs

lint is the umbrella verb: bare = the gate, --fix = apply, --affected/--from/--ci = scope.

CommandWhat it does
dotnet-fast lintVerify & 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 --fixApply all safe fixes in one pass. Scope with --affected, --from/--to, --ci, or --staged (pre-commit, re-stages fixes).
dotnet-fast affectedDotNetAffected-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 restoreLockfile-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 updateReport (or --apply) available package updates. --min-age is a supply-chain cooldown; --audit flags known-vulnerable (OSV) versions and gates CI.
dotnet-fast sbomCycloneDX 1.5 or SPDX 2.3 SBOM straight from packages.lock.json — no MSBuild, no build, no network.
dotnet-fast doctorBuild-free workspace health scan (duplicate/orphaned references, CPM & version smells, inconsistent locks). --json / --sarif / --strict.
dotnet-fast hooks installWrite managed pre-commit / pre-push Git hooks running lint --fix --staged — no husky/lint-staged needed.
dotnet-fast editorconfigexplain <file> traces the resolved config chain; init infers a .editorconfig from the existing sources.

UsageCommon workflows

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

0clean
1findings present (lint / bare dotnet-fast)
2dotnet format-compat verify/apply failure
3restore --verify-only found packages missing from the cache
4restore --no-fallback/--offline precondition, or update found no lock
166affected 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).