Avatar
← Back To Blog
mediatr.png

VibedMediatr: A Drop-In MediatR Alternative

User Avatar
YodasMyDad 6 days ago

Recently MediatR changed their license to a paid one. I get it, maintainers deserve to be compensated. But for those of us just wanting a simple mediator pattern without the licensing concerns, I built VibedMediatr. 

Why Another Mediator Library?

Let's be honest, 99% of MediatR usage is just IRequest, IRequestHandler, and IMediator.Send(). That's it. No behaviors, no pipelines, no notifications. Just clean, simple request-handling. 

VibedMediatr focuses exclusively on this core pattern. It's tiny, fast, and most importantly: it's a literal drop-in replacement. 

What Do I Mean by "Drop-In"? 

I mean you can swap it in with almost zero changes. Check this out: 

Your Existing MediatR Code

using MediatR;  // Still the same namespace!

public sealed record GetUserQuery(int UserId) : IRequest<User>;

public sealed class GetUserHandler : IRequestHandler<GetUserQuery, User>
{
    private readonly AppDbContext _db;
    
    public GetUserHandler(AppDbContext db) => _db = db;

    public async Task<User> Handle(GetUserQuery request, CancellationToken cancellationToken)
    {
        return await _db.Users.FindAsync(request.UserId, cancellationToken);
    }
}

Using It in a Controller

[ApiController]
[Route("api/[controller]")]
public class UsersController(IMediator mediator) : ControllerBase
{
    [HttpGet("{id}")]
    public async Task<IActionResult> Get(int id)
    {
        var user = await mediator.Send(new GetUserQuery(id));
        return user is null ? NotFound() : Ok(user);
    }
}

That code? Works exactly the same with VibedMediatr. No changes needed. 

The only difference is in your Program.cs:

// Replace this:
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));

// With this (Can be a list of assemblies)
builder.Services.AddVibedMediatr(typeof(Program).Assembly);

But Is It Actually Fast?

Short answer: yes.

VibedMediatr uses a two-phase approach, the first time you send a request type, it uses reflection to build a compiled delegate and caches it. Every subsequent call hits that cached delegate directly. No repeated reflection, no unnecessary overhead.

Is it as optimized as hand-rolling your own service resolution? Nope. But it's plenty fast for 99.9% of applications, and you get all the benefits of the mediator pattern.

What's Missing?

Here's what VibedMediatr doesn't have:

  • ❌ Notifications (INotification)
  • ❌ Pipeline behaviors
  •  ❌ Pre/post processors
  • ❌ Streaming requests

If you need those features, MediatR is still great (Just pay for the license to support the maintainer). But if you're like most of us and just need basic request/response handling, VibedMediatr gives you exactly what you need - nothing more, nothing less.

It's available on NuGet right now and you can view the code on Github

dotnet add package VibedMediatr
© 2025 - Powered By ZauberCMS
An unhandled error has occurred. Reload 🗙