Loading

Why not CSharpier?

CSharpier ships with a fixed, opinionated style that cannot be changed through configuration. It reads a small number of .editorconfig keys and ignores the rest — including nearly all of IDE0055. If your team already has a style configured in Rider or Visual Studio, CSharpier will rewrite files to its own choices rather than yours, and it will not stay in sync with Format Document in your IDE without installing a separate editor plugin.

curb reads the complete IDE0055 formatting surface and the ReSharper wrapping and blank-line keys. Its defaults are Roslyn's defaults — the same values Visual Studio and Rider already use. Format Document and curb agree out of the box, with no extra plugins required.

CSharpier ships with its own layout opinions. It reads a small number of .editorconfig keys and ignores the rest. If your team had already configured Rider or your IDE with a particular style — indentation, brace placement, spacing, blank lines — CSharpier will rewrite files to its own choices rather than yours.

curb reads the complete IDE0055 formatting surface, the 8 core EditorConfig keys, and the ReSharper wrapping and blank-line keys. The defaults are Roslyn's defaults, which are what Visual Studio and Rider already use. On a repository that has configured the IDE, the first run changes whitespace-within-lines and nothing about layout style.

What you set is what you get. curb invents no formatting keys.

Because CSharpier does not follow IDE0055, Format Document in your IDE and CSharpier can disagree. The recommended fix is to install a separate IDE extension (VS Code, Visual Studio, Rider) that makes the editor format to CSharpier's style instead.

curb needs no extension. Since its rules are the same IDE0055 keys the editor already reads, Format Document and curb agree without any additional setup.

Both tools have an MSBuild package. The difference is in how the build integration works.

CSharpier's MSBuild package runs CSharpier on every build. Its incremental story relies on a machine-global file hash cache:

$LocalApplicationData/CSharpier/.formattingCache
		

That cache is outside your repository and persists across git clean, git checkout, and fresh checkouts. A CI runner or a colleague on a new machine has no cache, so every run on those machines pays the full formatting cost.

curb's MSBuild target declares:

Inputs="@(Compile);@(EditorConfigFiles);$(MSBuildProjectFullPath)"
Outputs="$(Curb_StampFile)"
		

MSBuild evaluates the Inputs against the stamp before curb starts. On an untouched project — no changed source files, no changed .editorconfig, no changed project file — the target is skipped entirely and no process starts. Not "fast" — no process.

On a project where only one file changed, curb formats that one file, not the directory. The stamp file lives in $(IntermediateOutputPath) (your obj/ folder), is removed by dotnet clean, and autoinvalidates after one week. There is no machine-global state to debug or warm up.

These numbers are from the twelve-repository comparison.

Cold — cache cleared before each run. This is what CI sees on every run, and what a developer sees on a fresh checkout. Both tools pay their full cost.

repo curb (cold) CSharpier (cold)
serilog (216 files) 0.06 s 0.64 s
FluentValidation (219 files) 0.05 s 0.54 s
RestSharp (255 files) 0.08 s 0.69 s
logging-log4net (376 files) 0.14 s 1.21 s
AutoMapper (512 files) 0.10 s 1.16 s
Humanizer (733 files) 0.36 s 4.33 s
quartznet (765 files) 0.25 s 1.90 s
Newtonsoft.Json (945 files) 0.30 s 4.45 s
ServiceStack (4,718 files) 1.11 s 11.48 s
MassTransit (5,502 files) 0.56 s 4.23 s
efcore (5,761 files) 2.15 s 19.12 s
roslyn (17,167 files) 7.26 s 59.67 s

Cold is the relevant baseline for CI environments and for anyone evaluating whether the tool is fast enough to run on every build. curb is fast cold.

Warm, nothing changed — subsequent build where no source files were modified. curb evaluates the MSBuild stamp and exits; CSharpier walks and hashes every file to check its cache.

repo curb CSharpier (warm)
serilog no process 0.29 s
FluentValidation no process 0.19 s
RestSharp no process 0.34 s
logging-log4net no process 0.42 s
AutoMapper no process 0.42 s
Humanizer no process 0.46 s
quartznet no process 0.32 s
Newtonsoft.Json no process 0.22 s
ServiceStack no process 1.15 s
MassTransit no process 0.70 s
efcore no process 3.12 s
roslyn no process 5.12 s

On unchanged projects curb starts no process at all. CSharpier must still walk the entire directory tree on every build to update its cache, even when nothing changed.

Warm, files changed — subsequent build where files were modified. curb uses --cache to skip files whose output has not changed; CSharpier uses its file hash cache. Numbers below are worst-case: all files in the project were treated as changed.

repo curb (warm) CSharpier (warm)
serilog 0.03 s 0.29 s
FluentValidation 0.03 s 0.19 s
RestSharp 0.06 s 0.34 s
logging-log4net 0.05 s 0.42 s
AutoMapper 0.04 s 0.42 s
Humanizer 0.16 s 0.46 s
quartznet 0.06 s 0.32 s
Newtonsoft.Json 0.12 s 0.22 s
ServiceStack 0.22 s 1.15 s
MassTransit 0.20 s 0.70 s
efcore 0.49 s 3.12 s
roslyn 1.15 s 5.12 s

Even in the worst case — every file changed — curb beats CSharpier warm on every repository. In practice a typical build touches far fewer files, and curb reformats only those.

curb is FAST cold, FASTER warm.

The reason is architecture. curb builds a document IR in a pooled arena — structs, not objects, reusing memory across files. It loads no workspace and resolves no symbols. CSharpier uses a Prettier-style IR with per-file allocation, computes a content hash, and writes it to disk.

CSharpier requires committing to its built-in style. If your codebase currently has .editorconfig formatting rules, CSharpier will change them — you either adopt CSharpier's opinions wholesale or do not use it.

curb with no .editorconfig at all formats to Roslyn's defaults: the same output Visual Studio and dotnet format whitespace produce. There is no style to buy into. Adopt it project by project, and it agrees with what your IDE already does.

CSharpier has been around longer and has real-world adoption across a wide range of .NET projects. It has proven itself in production, accumulated community knowledge, and the rough edges have been filed down. That counts for something.

curb is new. The architecture is different, the goals are different, and the test suite is extensive — curb has broad formatting test coverage and its output is CI-gated to be byte-identical to dotnet format whitespace across 41,000 files — but it has not yet had the years of production use that CSharpier has.

That said, if any of the above differences matter to you — IDE0055 compatibility, no editor plugin, MSBuild-native incrementality, respecting your existing .editorconfig — we would love for you to give curb a try and tell us what you find.

If you want zero configuration and are happy with CSharpier's built-in style, it is a reasonable choice. If you have an existing .editorconfig — especially one configured through Rider or JetBrains tooling — curb will honour it. CSharpier will not.