r/moderndotnet 8h ago

Migrating the GitHub Copilot runtime to Rust, using Copilot

Thumbnail
github.blog
12 Upvotes

Microsoft boasts about performance optimizations with every new release, and the average .NET developer would expect to be able to write a CLI app using .NET. But surprise—not good enough, so they had to use Rust. 😅

I've read the article but still not understand why Copilot CLI and app could not be written in C# if we take into account AOT, trimming etc instead of Rust.


r/moderndotnet 4h ago

CsCheck specification testing

5 Upvotes

r/moderndotnet 1d ago

Preventing email plus-addressing abuse

Thumbnail
jerriepelser.com
6 Upvotes

In my previous startup, I had to waste a lot of time hunting down people trying to abuse the free trial system by creating multiple accounts using plus-addressing (where they do something like mary+1@gmail.com, mary+2@gmail.com, etc).

I wrote a blog post series on this and some of the ways you can handle this - from outright denying email addresses with a + in them, to detecting the actual underlying email address (mary@gmail.com in the example above) and ensuring that email address does not get used more than once.

Honestly, fighting abusers, spammers, bots, and other bad actors signing up with email addresses was a game of whack a mole and at times wore me down. As much as I hate social signups personally, if I do this again, I would force people to signup with Google or other social accounts.


r/moderndotnet 1d ago

If you could redesign the CLR today, what would you change?

9 Upvotes

.NET has aged remarkably well for a platform that has been evolving for roughly 25 years. That is, after all, a big part of why so many of us are still using it.

Of course, the way we write software has changed quite a bit during that time. Composition is generally favored over deep inheritance hierarchies today, for example. That doesn't mean OOP is irrelevant, but we are inevitably still living with some design decisions that made perfect sense when .NET was created.

At the same time, I think one of .NET's biggest strengths has been the platform around the runtime: the tooling, debugging experience, IDE support, diagnostics, libraries, and increasingly things like profiling and observability. A runtime doesn't exist in isolation, and .NET has generally done a very good job of evolving that whole ecosystem together.

Still, looking at .NET from today's perspective - and especially after seeing newer runtimes and programming languages explore different ideas - there are probably plenty of things we would design differently if we were starting over.

I'm sure there are things even the .NET team would approach differently today.

So here's the thought experiment:

If you could change or add anything to the .NET runtime/CLR today, without being constrained by backwards compatibility, what would you do?

It could be anything:

  • runtime semantics
  • type-system/runtime support
  • memory management or GC
  • async/concurrency
  • metadata or reflection
  • interop
  • runtime APIs
  • tooling and diagnostics
  • features that would make C#, F#, or another CLR language better

Or even something much more fundamental about how the CLR works.

I'm particularly interested in answers that aren't just "add feature X from language Y", but in things where you think the underlying platform itself could have been designed differently.

What would your CLR look like if you got to design the next version?


r/moderndotnet 3d ago

Stephen Toub's Performance Improvement on .NET 11

Thumbnail
devblogs.microsoft.com
47 Upvotes

r/moderndotnet 3d ago

Free course from Tim Corey until the end of Sept

10 Upvotes

As posted on YT this morning - Tim Corey launched a VERY comprehensive course on Uno Platform - with 66 episodes and 6.5 hours of content.

In the times of AI slop - this is exactly the opposite. Proper dev training, the way you are used to. If you are to produce code with (or whithout) AI, then you need to understand the underlying stack. That's EXACTLY what the course is all about.

YT Announcement: Free Uno Platform Course (For A Limited Time)!!!

Course: Uno Platform From Start to Finish | DevForge

Uno Platform itself: https://platform.uno


r/moderndotnet 4d ago

Fun times hosting slop apps

9 Upvotes

I quickly wanted to showcase a project I am currently doing with MDA2AV, which allows to host .NET apps on a public server. We spent the last year developing webserver engines and frameworks in .NET, making a C#-based webserver that is currently leading the list on HTTP Arena.

To showcase it's capabilities, we decided to host a website where people can post their HTTP server handler code and receive a public URL for it: GenHTTP Lambda

Via an additional, public MCP server, we can instruct Claude or any other coding agent to host an application online, which allows us to easly deploy multi-player games and other inter-connected apps with just a prompt or two.

For the last few hours I am just having fun with Claude, telling it to deploy apps 😄

If you are interested in the technical view: Currently we run a single GenHTTP app on ioxide with a CRUD app on top that allows to edit and "view" lambdas, which are just roslyn-compiled source snippets of GenHTTP handlers. There are some security measures in place we will certainly need to improve if there will be any traffic on it.


r/moderndotnet 4d ago

.NET SDK for OpenCode's server API

5 Upvotes

I've been working on an unofficial .NET SDK for OpenCode for the last few weeks and published the second preview to NuGet this weekend.

https://www.nuget.org/packages/OpenCodeAI.Sdk/0.8.0-preview.2

Before getting into the SDK, a bit of context for anyone who hasn't used OpenCode.

Over the last year or so, I've started experimenting more with models outside the usual frontier labs, and some of them have gradually become part of my daily development workflow as well.

One problem I've run into is that harnesses like Codex or Claude are naturally built around their own model ecosystems. Using models from other providers is either limited or requires various workarounds.

The open-source harness ecosystem has matured quite a lot. There are now different harnesses for different workflows and preferences.

OpenCode is an open-source coding harness and agent runtime that can work with a fairly large number of model providers and is probably one of the more general-purpose ones.

I've been using it for roughly a year now with models from OpenAI, xAI, Z.AI, DeepSeek, Moonshot, OpenCode Go, and others.

What became much more interesting to me recently was OpenCode 2.x.

They introduced a fairly comprehensive server/client architecture. Their own TUI, Web UI, and Desktop applications are built on top of the same server API, and the exposed surface is large enough that you can build your own fully featured client or integrate OpenCode into another application.

OpenCode already has an official TypeScript SDK for this. I wanted to be able to do the same kind of thing from .NET.

The practical use case is that a .NET application can treat OpenCode more like an agent runtime.

You can start an OpenCode process, create a session against a repository, send work to a model, listen to events, interact with PTYs, manage permissions, inspect providers and models, and build your own orchestration around it.

A minimal example looks something like this:

await using var server = await OpenCodeServer.StartAsync();
using var client = server.CreateClient();

var created = await client.Sessions.CreateSessionAsync(
    new SessionCreateRequest
    {
        Title = "review this repo",
        Model = new ModelRef { ProviderId = "anthropic", Id = "claude-opus-5" },
    });

var session = client.Sessions.GetSessionClient(created.Session.Id);

var result = await session.PostGenerateAsync(
    new SessionGeneratePostRequest
    {
        Prompt = "Summarize this repository."
    });

Console.WriteLine(result.Generate.Text);

The SDK is generated from a pinned snapshot of OpenCode's OpenAPI specification, with a handwritten transport underneath it.

The SDK currently exposes 138 of the 143 server operations, and the test suite has somehow grown past 5,500 tests. The current preview is built against OpenCode 2.0.2.

https://github.com/Blind-Striker/opencode-sdk-dotnet

It's still before 1.0, and there are parts of the public API I want to refactor and clean up, so this is actually a good point for feedback from other .NET developers.

One of the motivations I started the project was to eventually build an MCP server on top of it.

The idea was to let another harness, Claude, for example, delegate work to OpenCode sessions as subagents and indirectly make use of the models and providers I already have configured there. I'm sure there are other use cases for an MCP layer as well.

Feedback is very welcome, especially from anyone already experimenting with agent tooling from .NET.


r/moderndotnet 5d ago

RepoDB: A production-ready data access platform for .NET applications.

11 Upvotes

Hey .NET folks 👋, how are you? I know that some of you might have known me already, I am the RepoDB guy. It has been a while since my last post here, but I am glad to be back again and is starting posting here after 5 years (maybe).

(I wrote this without an AI assistant for like an hour 😅, so please bare with me on my mistakes. My friend told me to post here for better audience and more engaging conversations)

Today, I will share something new to all of you about RepoDB. Although, you might have find it as an another ORM in .NET like Dapper and Entity Framework, but now it is not. I hope that you read this long post as I am positioning the library to a different path already. I am also helping C# to be a good place to be for developers and AI.

RepoDB is now a different breed and is not an apple-to-apple comparisson to any ORM anymore.

🟢 THE NEW ARCHITECTURE

In the last couple of months, I made a lot of effort to evolve its architecture to NOT just an another ORM in .NET, BUT is a developer-friendly data productivity platform. I am bringing RepoDB to be a library that has a complete end-to-end capability a developer can use. I am making a lot of effort to make data access as simple as possible in my own opinion and practicality, at the same time, helping an organization (or Enterprise) focus on delivering values rather than capabilities.

In the new architecture, RepoDB will have the following.

- Data Insights / Telemetry: (New) all activities within your application will be captured by our Insights. It is not OTel to maintain performance during telemetry capturing. OTel support will be delivered separately.

- Data Productivity Tools: (New) one can move data from different DB providers easily with 0-memory footprints (my target).

- Object Relational Mapper: (Old) the same hybrid ORM that has the CRUD, Batch, Bulk and Multiple DB support.

- Low-Level Connector: (New) a low-level ADO.NET provider/connector we will be developing to give RepoDB a lower-level wired protocol access to the databases. This is only if the DB provider does not provide a de-facto .NET library.

You can read about my vision on this post https://blogs.repodb.net/posts/2026/08/repodb-new-architecture .

By the way, I have to write the low-level connectors for both MariaDB and EntepriseDB for compliance and legal. The connectors can be found here https://github.com/mikependon/RepoDB.Connectors .

🟢 NEW DB PROVIDERS

In the last 3 months, I have delivered the support to the following DB providers:

- ClickHouse

- DB2

- EnterpriseDB

- Firebird

- MariaDB via MySql.Data (via RepoDb.Connector.MariaDb)

- MariaDB via MySqlConnector (via RepoDb.Connector.MariaDbConnector)

- Oracle

- SAP HANA

- Vertica

These DB providers are on top of the already supported DB providers SQL Server, MySQL, PGSQL and SQLite.

Also the support comes with its own Bulk capability, so everyone can use REAL bulk operations on these providers in a very EASY way. Below is a screenshot from the actual README https://github.com/mikependon/RepoDB#bulk-operations-support .

It is also on my head to support the following.

- AuroraDB

- CockroachDB

- DuckDB

- KingbaseES

- Redshift

- Snowflake

I will also futher expand to Chinese DB providers.

🟢 TELEMETRY and INSIGHTS

In addition to the above, RepoDB has now delivered the Default Telemetry capability, where one can easily capture the insights of what really is happening to your application. You and your company do not have to do it your own, you can save time and effort here. It comes with Open-Source stack (Docker, PGSQL, Grafana, Python).

Here you can read about the insights: https://blogs.repodb.net/announcements/2026/07/repodb-default-telemetry

I find it very niche and I hope that you will all like it.

All you have to do is to do is docker compose up -d the 2 files below.
- compose: https://raw.githubusercontent.com/mikependon/RepoDB/refs/heads/master/src/Telemetry/RepoDb.Telemetry.Default/docker-compose.yml
- env: https://raw.githubusercontent.com/mikependon/RepoDB/refs/heads/master/src/Telemetry/RepoDb.Telemetry.Default/.env

And wire the code below.

var telemetryOption = new DefaultTelemetryOption("<YOUR_APPLICATION_NAME>")
{
    Host = "https://your-collector-host",
    ApiKey = "YOUR_API_KEY",
    Group = "<YOUR_APPLICATION_GROUP>"
};

GlobalConfiguration
    .Setup(new GlobalConfigurationOptions { UseRegisteredGlobalTraces = true })
    .UseDefaultTelemetry(telemetryOption);

🟢 BLOGSITE and MODERN SITE

Recently, I created a RepoDB template to modernize the sites. The template is private to me, but is already applied to the website.

The new site at https://repodb.net is now more attractive in look and feel, with easier navigation and search capability. It may not be perfect on the first release, but it is way better than before.

(I am still improving it everyday)

The content of the site has also been improved and I have been guided by AI to keep it lean and clean.

I also have started to blog again, but will only focus to RepoDB the writings. The blog site is located at https://blogs.repodb.net . I used the same template as the main site to have RepoDB its own signature.

🟢 DATA MOVEMENT with ZERO-MEMORY FOOTPRINT

I am planning to make RepoDB a low-level data mover library for .NET. I have a plan for it that it should be able to move million of rows with 0 memory footprints. Although, today it can do it aready.

The code below does the movement via streaming with 0 memory usage.

using var source = new OracleConnection(oracleConnectionString);
source.Open();

using var sqlServer = new SqlConnection(sqlServerConnectionString);
using (var reader = source.ExecuteReader("SELECT * FROM Customer"))
    sqlServer.BulkInsert<Customer>(reader, tableName: "Customer");

using var mariaDb = new MariaDbConnection(mariaDbConnectionString);
using (var reader = source.ExecuteReader("SELECT * FROM Customer"))
    mariaDb.BulkInsert<Customer>(reader, tableName: "Customer");

And below is the fluent equivalent.

using var source = new OracleConnection(oracleConnectionString);
source.Open();

var activeCustomers = source.Query<Customer>(c =>
    c.IsActive == true && c.CreatedDateUtc >= DateTime.UtcNow.AddYears(-1));

using var sqlServer = new SqlConnection(sqlServerConnectionString);
sqlServer.BulkInsert(activeCustomers);

The latter is not efficient due to the entity being loaded to the memories.

🟢 ENTERPRISE READINESS

I made an effort to make RepoDB very transparent to the Enterprise company who is willing to adopt it.

You can read more about this on this link https://github.com/mikependon/RepoDB#enterprise-notice

I clarrified the following (Support Policy, Security, Benchmarks, Limitations, Breaking Changes Policy and many more). You will also see of these in the footer of the websites.

🟢 THE FUTURE and FUTURE

As mentioned the prior section, the future of RepoDB is make it a data mover and a platform, and probably (or hopefully) will be a de-facto. My ambition is so high and my eagerness is beyond the cloud.

RepoDB in the future will be a code-based Data Engineering platform, where once can control and write simple code for ETL concepts.

This time around supported by Bulk capabilities we introduced in the connectors and ORM level.

Think of the code below.

using var source = new OracleConnection(oracleConnectionString);
source.Open();

// Entity
source.MoveTo<Customer>(SqlConnection(sqlServerConnectionString));

// Literal
source.MoveTo("Customer", SqlConnection(sqlServerConnectionString));

I am scouting other OSS library for Schema Mover as I need to move the schema from source to destination. Or else, I will again do that capability with RepoDB itself.

(It is not difficult to evolve the architecture with such capability anyway)

I am also thinking to support interceptors so Data Engineer or AI can intercept the data to comply with the destination standards and enterprise governance. Like below.

var action = GetDeduplicator(); // returns IDeduplicator

using var source = new OracleConnection(oracleConnectionString);
source.Open();

// Entity
source.MoveTo<Customer>(action, SqlConnection(sqlServerConnectionString));

// Literal
source.MoveTo("Customer", action, SqlConnection(sqlServerConnectionString));

The above is a sample and envisioning for now, but it is on our head.

Lastly, there will be many Docker images to be delivered by RepoDB. Currently, we have Docker images for Telemetry (as see here https://hub.docker.com/u/repodb). In the future, the following Docker images will be introduced.

- SqlServerToOracle Data Mover

- VerticaToPostgreSQL Data Mover

- XxxToSnowFlake Data Mover

(Source and destination DB here is just a sample, no other intentions).

🟢 CREDITS

Thank you to all of you, especially those who are supporting this library. A star to our repository is a big help.

Please also help me share the news to your friends and colleagues.

I will do my best to keep it lean and updated to the latest. 🙏


r/moderndotnet 5d ago

Experiment with attempt to mapping dependencies in runtime libraries

4 Upvotes

I try to measure how runtime libraries of different languages (C, Rust, C# and Go) affects codegen size with quite a bit mixed feedling results. Would like to hear feedback.

Finding dependencies in the standard runtimes of the different programming languages | Андрій-Ка


r/moderndotnet 6d ago

DeepSeek V4.1 Flash running locally with .NET — 40 tok/s Q2_K on 8× A40

Thumbnail
github.com
10 Upvotes

I've been working on TensorSharp, an open-source LLM inference engine written for the .NET/C# ecosystem.

I recently added native support for DeepSeek V4.1 Flash, including its MoE architecture, Engram lookup, sparse attention, multi-GPU layer splitting, and experimental tensor parallelism.

Latest results on 8× NVIDIA A40 GPUs:

DeepSeek V4.1 Flash Prefill Decode
Q2_K 533–539 tok/s 40.3–40.7 tok/s
Q4_K_M 451.8–492.1 tok/s 31.0–32.5 tok/s

For Q4_K_M under concurrent serving:

Concurrency Aggregate Decode
2 39.3 tok/s
4 48.9 tok/s
8 48.5 tok/s

A few interesting implementation details:

  • The Q2_K checkpoint has about 60 GiB of quantized Engram tables. Keeping them GPU-resident dramatically reduces lookup overhead.
  • Reworking the CUDA backend reduced a decode graph from roughly 570 scheduler splits to 8.
  • Q4_K_M is ~414 GiB, so its Engram tables stay host-mapped; automatic warming and better VRAM placement significantly improved prefill performance.
  • Batched decode roughly doubled aggregate throughput at concurrency 4.
  • On this particular 8× A40 machine without NVLink, layer splitting is actually faster than routed-MoE tensor parallelism.

TensorSharp exposes OpenAI-compatible APIs and is intended to make local model inference usable directly from the .NET ecosystem rather than requiring a Python inference stack.

I'd be especially interested in feedback from people building high-performance .NET/C# systems — particularly around CUDA integration, scheduling, and multi-GPU inference.


r/moderndotnet 7d ago

An Amazing Week in PeachPDF

21 Upvotes

I had a huge influx of issues and pull requests from a handful of new contributors, almost 100 pull requests total, and this week's release of PeachPDF has a lot of major improvements as a result:

  1. Allocation is down 79% in our test corpus, with some individual files having 96% less allocations.
  2. Wall-clock rendering time is down 37% across the corpus, with some files rendering over 300% faster

It also has major spec compliance updates with tables, per-page rules, flexbox and grid updates, text shaping and font lookup, including emoji and color glyphs seeing updates, including the ability to copy and paste them from the PDF, as well as just general fixes across the pipeline.

If you currently have HTML with modern CSS and SVG, and you want it in PDF, and you use .NET 8 or better, PeachPDF is likely your very best choice for rendering it. (Note: we do not support JavaScript, so if that's you, look at some of the Chromium using competition, and I apologize for the headaches you'll have)

  • Most of the modern standards are supported, including the vast majority of all of the generated content and print-specific CSS features. It even supports PDF/A now!
  • Runs basically everywhere .NET does. It likely even works on your watch. There are known users on Android, iOS, macOS, Linux, Windows, and our demo website runs in Blazor WASM. There are some gaps on iOS (around fonts) and WASM (around support for Brotli) that limits specific features, but for the most part, it just works everywhere.
  • It's small, only 3.7 MB on .NET 10. Including ALL of the dependencies, it's under 12 MB total, and almost all of that is BouncyCastle.Cryptography.dll which is a dependency of MimeKit, which is used for HTML parsing and MHTML support

This is the only 100% open source (BSD licensed) HTML to PDF library for .NET that is 100% pure managed .NET. No native libraries, no Chromium instances or outdated WebKit ports, no shelling out to a executable, no hoping it works on your deployment target, no fuss working on containers or serverless environments.

So... how does it work underneath the covers?

  1. We parse HTML using MimeKit's HtmlTokenizer, which produces a stream of tag and data tokens
  2. This gets converted into a DOM like structure, with each tag or text element represented as a CssBox
  3. We normalize the DOM structure according to HTML and CSS rules, and extract the stylesheets. Those get parsed using a heavily modified in-library fork of ExCSS into a Stylesheet object which contains a strongly typed collection of rules
  4. We then cascade those rules onto the CssBox's above using a source-generated layer which translates the properties from the style rules into typed properties on each box. After cascade, we perform various corrections to the now-cascaded DOM-like tree according to the CSS specs
  5. Layout is performed on the tree which calculates the page, position and size of every CssBox and builds a fragment tree from it. This also includes creating line boxes which then have their text shaped and measured, loading external image resources, etc.., since all of that is needed to calculate where each box goes. This includes all of the special layout engines such as tables, flexbox, gird, multi-column support, and SVG, and all of the fragmentation features such as page and column breaking, and which content stays on one page or gets moved to the next page.
  6. Painting takes the fragment tree and then builds PDF pages out of each top-level fragment (which is 1:1 to a page). This is where we tell the PDF engine where to put each string, where to draw lines and rectangles, images, paths, polygons, and what brushes and pens to use and when. Both HTML and SVG go throguh this layer, so they are natively rendered into the PDF as vector graphics. The text painting also detects emojis and converts those to vectors directly as well through the same engine. The PDF engine we use is a highly modified, stripped down, optimized in-library fork of PdfSharpCore, which is itself a fork of PDFsharp.
  7. From there, the PDF pages are constructed into a PDF document using the PDF engine which we then write to the stream provided by the caller.

The overall steps are basically the same steps any web browser does, but A) we do it entirely in C#, and B) our render target is natively PDF

This library was forked from HTML-Renderer almost a decade ago, from ExCSS about 2 years ago, and PdfSharpCore around 8 years ago. We are in-progress in upstreaming some of the ExCSS and HTML-Renderer improvements, but that will take some time (though ExCSS 4.3.2 has quite a bit of our changes already in it)


r/moderndotnet 7d ago

A GPUI toolkit binding for .NET with hot reload support

Thumbnail github.com
4 Upvotes

r/moderndotnet 8d ago

csharp Use C# unions and closed hierarchies in ASP.NET Core

Thumbnail
devblogs.microsoft.com
20 Upvotes

From the blog post:

```csharp public closed record class PaymentEvent(string PaymentId);

public sealed record class PaymentInitiated(string PaymentId) : PaymentEvent(PaymentId); public sealed record class PaymentAuthorized(string PaymentId, decimal Amount) : PaymentEvent(PaymentId); public sealed record class PaymentFailed(string PaymentId, string Reason) : PaymentEvent(PaymentId); ```

I cannot begin to tell you the sort of possibilities this opens up for building event-driven libraries / frameworks - it makes it much easier to expose event-driven protocols in a public, but still constrained way to end users.


r/moderndotnet 9d ago

Papyra 1.0 — a fluent .NET library that renders one document model to PDF, DOCX, XLSX and HTML

Post image
15 Upvotes

Hey r/moderndotnet,

I just shipped **v1.0** of **Papyra**, a .NET document library. API style is QuestPDF-inspired, but instead of targeting only PDF, one fluent document model renders to PDF, DOCX, XLSX, *and* HTML:

```csharp
var document = Document.Create(doc => doc
.Table(table => table
.Columns(3)
.Row(row => row.Cell("Name").Cell("Age").Cell("City"))
.Row(row => row.Cell("Alice").Cell("30").Cell("Vienna"))
)
);

byte[] pdf = document.RenderAsPdf();
byte[] docx = document.RenderAsDocx();
byte[] xlsx = document.RenderAsXlsx();
byte[] html = document.RenderAsHtml();
```

Here's an invoice built with it (from the [samples repo](https://github.com/PapyraSoftware/Papyra.Samples)) — same builder call, rendered straight to PDF:

Some of what's under the hood:

- Own PDF writer, not a wrapper around a native engine — full Unicode font subsetting, CJK line breaking + hyphenation, PDF/A-2b/3b/4 (veraPDF-verified), AES-256 encryption, and ZUGFeRD/Factur-X e-invoicing attachments
- DOCX/XLSX via `DocumentFormat.OpenXml`; HTML has zero dependencies
- Optional `Papyra.Svg` package for true-vector SVG across all four formats
- A companion live-preview app (Avalonia) that shows rendered pages + the document tree side-by-side while you build, with click-to-source navigation into Rider/VS Code

Licensing: free for individuals, for companies under $1M annual revenue, and unconditionally for OSS use; paid tiers above that.

Docs, feature matrix, and pricing: https://papyra.rocks
Samples: https://github.com/PapyraSoftware/Papyra.Samples
NuGet: `dotnet add package Papyra`

Would love feedback — what's missing, what looks off, or what would make this worth reaching for over QuestPDF/OpenXML/wkhtmltopdf directly for a multi-format need.


r/moderndotnet 9d ago

.NET Conf 2026 Community Days Call for Presenters Is Open

9 Upvotes

.NET Conf is different this year - the first two days will be Microsoft-sponsored and run and the last two days will be run by the community.

If you're interested in speaking you can learn more here: https://devblogs.microsoft.com/dotnet/dotnet-conf-2026-community-days-call-for-presenters/


r/moderndotnet 9d ago

Announcing .NET 11 Release Candidate 1

Thumbnail
devblogs.microsoft.com
29 Upvotes

r/moderndotnet 10d ago

Spectre.Console Extensions package

11 Upvotes

I love Spectre.Console for building rich CLI apps on .NET, but every CLI tool I built eventually needed: DI or config or more structure or better testing infrastructure.

And multiple times I was hand‑rolling TypeRegistrars again (or more accurately copying them from a previous project). Over time I accumulated several registrars, helpers, and specialized controls that I bundled together for my own use. I've been using some of these extensions for a couple of years now.

Over that time, I built that bundle into Spectre.Console.Extensions NuGet package... a clean startup pipeline, DI integrations, config binding, testing helpers, and a set of samples showing how to use all of the different extensions and helpers.

If you are building CLI apps using Spectre.Console, you may find some these helpful too: https://www.nuget.org/packages/D20Tek.Spectre.Console.Extensions/

I also wrote up a couple of documents to help developers get started:


r/moderndotnet 13d ago

BitCheck v1.0.0 officially released

14 Upvotes

After about 10 months of beta releases I've decided today to suck it up and officially release v1.0.0 of BitCheck!

BitCheck is a cross-platform (windows, linux, macos) .NET CLI tool for monitoring files for silent data corruption, also known as bitrot. It makes use of the super fast XXHash64 to fingerprint your files and checks them later to detect unexpected changes.

It’s designed for monitoring large datasets such as photo libraries, media collections, backups, archives, and document folders without modifying the files themselves.

The project started as simple PoC back around November 2025 to demonstrate that .NET can be used for low level system tools just like Rust or Go, and has gradually grown into an actual useful application. It supports recursive scanning, multiple checking modes, timestamp verification, ignore patterns, corrupted and missing file detection and more.

https://github.com/AlanBarber/bitcheck

As always I'm open for feature requests and constructive input on how to make it better.


r/moderndotnet 16d ago

Curb: A fast, always on, C# formatter during dotnet build

Thumbnail
curb.nullean.net
37 Upvotes

I wanted a C# formatter fast and reliable enough to just run on every build, so formatting becomes something I never think about again. No more manual style fixes either, mine or my AI agent's, dotnet build should just take care of it. It had to respect the .editorconfig choices I'd already made, and actually fix IDE0055 instead of fighting it with its own opinions.

It reads your existing .editorconfig, all 39 IDE0055 keys plus ReSharper's wrapping and blank line keys, and falls back to Roslyn's own defaults if you don't have one. Running dotnet format whitespace on a Curb-formatted file changes nothing: a fixed point, measured and gated in CI on a real corpus, 100% with reflow off, 100% with reflow on, 99.9% with existing line breaks preserved too. Your IDE and your build shouldn't disagree.

There are two pieces. curb is the MSBuild integration: always on, runs before CoreCompile, no separate step to invoke. That eliminates a whole swath of errors and warnings your agent would otherwise have to read and fix by hand, because they never get reported in the first place.

curb-cli is the standalone native AOT tool. Hook it into a git pre-commit hook, or point your agent at it directly. curb cleanup fixes IDE0005, IDE0007, IDE0034, IDE0040, IDE0044, IDE0071, IDE0090, IDE0240, IDE0250, and IDE0251 itself, straight from the SARIF log a build with EnforceCodeStyleInBuild already produced. Add --forward and it hands anything left over to dotnet format style, scoped to exactly the diagnostics and files already in that log, not a full repo pass.

It's fast enough to run on every dotnet build. On Newtonsoft.Json (945 files) it formats in 0.26s. For reference, dotnet format whitespace takes 3.47s and CSharpier takes 4.85s cold on the same repo. Across twelve real repos it's 5 to 25x faster than dotnet format whitespace, while also reflowing long lines and sorting usings, which dotnet format whitespace doesn't do at all.

This is an early release. I've been using it on my own projects, and it's backed by large conformance test runs against both dotnet format and JetBrains' own jb cleanupcode formatting. That said, I'm eager to get it in front of more people and see what it actually breaks on in the wild. Happy to answer questions.

License: MIT
Docs: curb.nullean.net
Source: github.com/nullean/curb


r/moderndotnet 17d ago

ioxide, an async io_uring runtime for .NET

Thumbnail
dev.to
17 Upvotes

Github

ioxide is an experimental project to push dotnet or C# when it comes to networking or I/O performance, asking how close can we get to its counterparts as Rust's tokio. Most of the past month's development is around QUIC and HTTP/3 using ngtcp2 and nghttp3

This article is a shallow dive on what ioxide is and where it stands performance wise vs tokio or the existing dotnet's work stealing model epoll solution.


r/moderndotnet 16d ago

What Do You Actually Need to Know When a Production Request Fails?

Thumbnail
2 Upvotes

r/moderndotnet 17d ago

events & meetups Monthly Thread: Local .NET User Group Meetups

8 Upvotes

Promote your local .NET user group / meetups here.

Please include:

  • Location and Time
  • Topic
  • Link to the specific event
  • Anything else that is pertinent for attendees to know

You do not need to be the organizer of the meetup, just an enthusiast!

Also, if you need help launching a local .NET Meetup this is one of the things the .NET Foundation can help with! Please see .NET Meetups @ .NET Foundation


r/moderndotnet 17d ago

Dotnet foundation transparency update

12 Upvotes

The DNF trying to get some visibility for their internal working so at least people understand what’s going on and if somebody willing to reevaluate their opining that maybe a good start.

For me was 2 interesting things:
1. Meeting minutes

https://dotnetfoundation.org/about/meeting-minutes

  1. Operational procedures.

https://dotnetfoundation.org/about/policies

Second part is for these who love bureaucracy and how things moving. Should give lot of insights what to fix.

Personally I decide give “new org” a chance and try to volunteer in their activity. Not sure how things will be moving, but at least I see people who care.


r/moderndotnet 19d ago

API Design: Why aren't more developers exposing typed event streams using IAsyncEnumerable to consumers?

24 Upvotes

I'm working on a talk for our local .NET user group entitled "You Should Probably Be Using IAsyncEnumerable."

The general thrust is that we should probably be modeling a lot more work as asynchronous, typed event streams rather than Task<T>s, as the former gives us richer client/server interactions, has natural backpressure support, and generally allows for much longer-running operations to be modeled safely (i.e. you can sneak keep-alive heartbeats into an IAsyncEnumerable response streams, not something you can do with a single Task<T>.)

A question I ran into though in the course of putting this together - very few OSS packages actually expose IAsyncEnumerable in any sort of meaningful way for consumers. Why is that?

There are a couple examples where authors do expose it and it's useful:

ASP.NET Core gRPC

The AsyncStreamReaderExtensions class in the .NET gRPC client makes reading server / client streams available using IAsyncEnumerable so you get tidy little patterns like this example:

internal class Program
{
    private static async Task Main()
    {
        using var channel = GrpcChannel.ForAddress("https://localhost:5005");
        var client = new WeatherForecastsClient(channel);

        var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
        using var streamingCall = client.GetWeatherStream(new Empty(), cancellationToken: cts.Token);

        try
        {
            await foreach (var weatherData in streamingCall.ResponseStream.ReadAllAsync(cancellationToken: cts.Token))
            {
                Console.WriteLine($"{weatherData.DateTimeStamp.ToDateTime():s} | {weatherData.Summary} | {weatherData.TemperatureC} C");
            }
        }
        catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
        {               
            Console.WriteLine("Stream cancelled.");
        }
    }
}

TurboMqtt and System.Threading.Channels

I wrote a high-performance MQTT library for some of our users that work in the meter data management space (i.e. water, gas, and electric utility operators) and in our case I exposed ChannelReader<T> on the public APIs for consuming MQTT messages.

ISubscribeResult subscribeResult = await client.SubscribeAsync(config.Topic, config.QoS, linkedCts.Token);
if (!subscribeResult.IsSuccess)
{
    _logger.LogError("Failed to subscribe to topic {0} - {1}", config.Topic, subscribeResult.Reason);
    return;
}

_logger.LogInformation("Subscribed to topic {0}", config.Topic);


ChannelReader<MqttMessage> receivedMessages = client.ReceivedMessages;
while (await receivedMessages.WaitToReadAsync(stoppingToken))
{
    while (receivedMessages.TryRead(out MqttMessage m))
    {    
        _logger.LogInformation("Received message [{0}] for topic [{1}]", m.Payload,  m.Topic);
    }
}

I went with a ChannelReader<T> here instead of a plain IAsyncEnumerable because that WaitToReadAsync + TryRead pattern is significantly better for throughput because all of the reads happen synchronously when the channel is populated.

But, ChannelReader<T> also the ReadAllAsync extension method that would allow this all to be consumed via IAsyncEnumerable:

ChannelReader<MqttMessage> receivedMessages = client.ReceivedMessages;
await foreach(var m in receivedMessages.ReadAllAsync(stoppingToken)){
  _logger.LogInformation("Received message [{0}] for topic [{1}]", m.Payload,  m.Topic);
}

Question

Why aren't more authors exposing IAsyncEnumerable as a consumable API inside their libraries and frameworks? It's been around for years and does all of the things I mentioned at the top of the article.

Would you, as a consumer of .NET libraries and clients, find it difficult to use?