A C# formatter built into dotnet build. It reads the .editorconfig
you already have, agrees with dotnet format and your IDE, and fixes the mechanical
work before the compiler reads a line. Formatting just happens.
// what it is
Most formatters are a step you have to remember: before commit, in CI, via a pre-push hook.
Curb runs before CoreCompile on every dotnet build. By the time the
compiler reads a file, the style is already applied.
Speed is not the goal — it is what makes running unconditionally possible. Curb never loads a compilation, ships as a native binary with a 10 ms start, and is skipped entirely by MSBuild when nothing changed.
where the time goes →All 39 IDE0055 options, the 8 core EditorConfig keys, wrapping, blank lines, trailing commas, expression bodies. Defaults are Roslyn's. Curb invents no keys — where Rider already had an opinion, Curb reads Rider's key rather than creating a competing one.
the full option reference →
Curb's output is a fixed point of dotnet format whitespace — measured and gated
in CI on every push. Hit Format Document in the IDE and nothing moves. Run
EnforceCodeStyleInBuild and the IDE0055 diagnostics are gone before the compiler
sees them.
// how it works
Curb runs before CoreCompile, so the compiler reads source that is already formatted.
The mechanical offences are not reported — they are gone.
No second config file. Add max_line_length when you want reflow; leave it out and Curb will never wrap a line for you.
Build-only — no library, nothing in your output. Drop it in Directory.Build.props to cover a whole solution.
Files are rewritten in Debug and checked in Release. A developer wants the fix; CI wants to be told. An untouched project pays nothing: no process start, no directory walk.
[*.cs] indent_style = tab max_line_length = 120 # opt into reflow csharp_new_line_before_open_brace = all csharp_prefer_braces = true csharp_style_namespace_declarations = file_scoped
<PackageReference Include="curb" Version="*" PrivateAssets="all" />
Rewriting code unattended is only reasonable if it cannot go wrong. Every file is verified in memory before anything is written — the tokens emitted must match the tokens parsed — and a file that fails is reported and left exactly as it was. Syntax Curb has not learned yet is emitted verbatim, so it is incomplete long before it is ever destructive. How it is checked →
// where the time goes
Newtonsoft.Json — 945 files, no .editorconfig. Wall-clock time, best of three runs.
dotnet format whitespaceCurb ships as a native-AOT binary — about 10 ms to start, no warm-up cost. MSBuild skips it entirely when the project is untouched: no process start, no directory walk. Full benchmark table →
// scope
Style rules split by what they need to know. The split is not an implementation detail — it is
why Curb can run before the compiler and still leave nothing for dotnet format to
do afterwards.
Decided from the parse tree alone. No restore, no compilation, no project system — runs before CoreCompile, rewrites the file, and the compiler reads formatted source.
max_line_lengthRuns on the diagnostics the compiler already reported. Applies fixes the build already knows how to make — no extra analysis step, no separate command to remember.
// for coding agents
Style rules written as prose in an AGENTS.md get followed inconsistently, and
every correction is a round trip: the agent writes, the build complains, the agent edits, the
build runs again. Every one of those edits is mechanical — there was one right answer, and it
was already in your .editorconfig.
Put the rules where they belong and let the build apply them. The agent never sees the mechanical offences, never spends a token on them, and never has to be told about them. What reaches it is the part that needed judgement.
## Style Formatting and syntax-level code style are applied automatically by the build — see .editorconfig. Do not hand-format code, and do not "fix" formatting you see in a diff. dotnet build will do it.
// packages
The MSBuild package wires Curb into the build and needs no further configuration. The CLI is for standalone formatting outside a build — scripts, editors, CI steps that run without the SDK project system.
Build-only — PrivateAssets="all" keeps it out of your output. Drop one
PackageReference in Directory.Build.props to format every project
in a solution. Nothing else to configure.
A global dotnet tool. Format or check a directory tree from the command line — useful in
editors, Git hooks, or CI pipelines that do not go through dotnet build.
The .editorconfig you already have. Nothing new to learn.
Nothing to remember to run. Just dotnet build.