Shipping Meridian: An Open-Source .NET Mediator and Mapper
Meridian is a small .NET library I released as two NuGet packages: Meridian.Mediator for CQRS-style in-process request handling and Meridian.Mapping for object-to-object mapping with profiles and query projection. It targets .NET 8 through 11, it is intentionally small in surface area, and it came out of years of carrying hand-rolled versions of these utilities from project to project.
Why Ship a New Mediator
The .NET ecosystem has strong options in this space already. I did not set out to compete with them. I wanted a mediator that kept my most-used patterns, dropped the ones I never reached for, and stayed readable enough that any team could fork it without friction. The goal was not novelty. It was clarity.
Meridian.Mediator focuses on four patterns that cover almost every real case I use: request and response, notifications, streams, and pipeline behaviors. Behaviors are the place where most projects grow their telemetry, validation, and caching wrappers, so Meridian makes that the primary extension point rather than an afterthought.
Why Include a Mapper
Mapping libraries are controversial. Some teams love them and some teams treat them as a source of debugging pain. I include Meridian.Mapping because the alternative is usually a folder of manual mappers that drift out of sync, not a cleaner architecture. The package supports profiles, resolvers, converters, and query projection, which together cover the places where hand-rolling gets expensive.
The feature I use most is query projection. Mapping an IQueryable to a target shape at the database level, instead of materializing the whole entity first, is a simple change that pays off immediately in large read paths.
Testing Discipline That AI Enforces
A library lives or dies on its test suite. Meridian has dense coverage across the behavior boundary between mediator pipeline, handlers, and scoped service resolution. I used AI help during development to generate exhaustive test matrices, then reviewed and rewrote the ones that were shallow. The generated cases were especially useful for the mapper, where edge cases are combinatorial and easy to forget.
I kept one rule: AI drafts a test, I decide whether it earns a place. Tests that only exist to pad coverage numbers get cut. Tests that describe real behavior that future maintainers might break get locked in and documented.
Keeping the Public Surface Small
An open-source .NET library is promising a contract to its users. Every public API is something I will regret breaking later. I resisted the urge to expose helpers that felt useful but were not strictly needed. I trimmed multiple methods between the first internal version and the first public release.
The smaller public surface made the versioning discipline easier too. If I can list the exports on one page, I can reason about backward compatibility every time I open a change. That discipline is worth more than any single feature.
The Release Workflow That Actually Ships
The part of open-sourcing a library that hurts is not the code. It is the packaging. I invested early in a release workflow that ran tests, built for every target framework, and pushed the packages with consistent metadata. AI was again useful here, mostly for catching my own mistakes in the workflow definition. A good release workflow disappears from your attention after the first two uses, which is exactly what you want.
Why Small Libraries Are Worth It
I have shipped enough application code to know that most projects do not need a new mediator or a new mapper. They need dependable ones. Meridian is not trying to win on features. It is trying to be the kind of library I would want to find in an unfamiliar codebase: obvious, quiet, and easy to replace if it ever stops fitting. That ambition is smaller than most library pitches, and that is the point.