EventMesh is a broker-agnostic distributed messaging platform for .NET. Write your application once against a unified API and deploy against RabbitMQ, Kafka, Redis Streams, Azure Service Bus, AWS SQS, Google Pub/Sub, or NATS JetStream without changing business logic.
EventMesh combines the developer experience of MassTransit and NServiceBus with the interoperability of CloudEvents, the observability of OpenTelemetry, and a capability-driven emulation engine that bridges broker differences transparently.
Project status: EventMesh is under active development (v0.1.0). NuGet packages are published on tagged releases. Broker adapters are compatibility-tested (beta) — see the Broker Capability Matrix for current coverage.
- Unified messaging API —
PublishAsync,ScheduleAsync,RequestAsync,ReplayAsync, andSubscribeAsyncon a singleIMessageBusabstraction - Seven broker adapters (compatibility-tested, beta) — RabbitMQ, Kafka, Redis Streams, Azure Service Bus, AWS SQS, Google Pub/Sub, NATS JetStream, plus InMemory for tests and benchmarks
- Capability model — Each broker declares supported features; the runtime emulates missing capabilities where safe
- Reliability patterns — Transactional outbox, idempotent inbox, retry policies, dead-letter queues, and saga support
- CloudEvents envelope — Canonical wire format with pluggable serializers (JSON today; MessagePack, Protobuf, and Avro planned)
- Observability-first — OpenTelemetry traces, Prometheus metrics, structured logs with correlation and causation IDs
- Control plane — Optional management API, React dashboard, and
eventmeshCLI for operations and visibility - Plugin architecture — Extend serialization, compression, encryption, authentication, and exporters via versioned plugins
- .NET 10 SDK
- Docker (for local brokers and integration tests)
dotnet add package EventMesh.Core
dotnet add package EventMesh.Transport.RabbitMQNuGet packages are published when a version tag (for example v0.1.0) is pushed. Until the first release, reference projects from this repository.
docker compose -f docker/docker-compose.yml up -dEventMesh registers a transport factory, wires it through UseTransport(...), and exposes IMessageBus from DI. The deferred factory pattern below matches the samples in samples/BrokerSwitching and avoids a host-build cycle:
using EventMesh.Abstractions.Messaging;
using EventMesh.Abstractions.Transport;
using EventMesh.Core;
using EventMesh.Transport.RabbitMQ;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var hostBuilder = Host.CreateApplicationBuilder();
// 1. Register the broker transport factory
hostBuilder.Services.AddRabbitMqTransport(options =>
{
options.HostName = "localhost";
options.Port = 5672;
options.UserName = "eventmesh";
options.Password = "eventmesh";
options.VirtualHost = "eventmesh";
});
// 2. Register EventMesh and select the transport
IHost? host = null;
hostBuilder.Services.AddEventMesh(mesh =>
mesh.UseTransport(new DeferredTransportFactory(
() => host!.Services.GetRequiredService<RabbitMqTransportFactory>(),
"rabbitmq")));
host = hostBuilder.Build();
await host.StartAsync();
// 3. Publish and consume
var bus = host.Services.GetRequiredService<IMessageBus>();
await using var consumer = await bus.SubscribeAsync<OrderCreated>(
async (order, ct) => Console.WriteLine($"Order {order.OrderId}: {order.Amount:C}"),
cancellationToken: CancellationToken.None);
await bus.PublishAsync(new OrderCreated(Guid.NewGuid(), 42.50m));
public sealed record OrderCreated(Guid OrderId, decimal Amount);
internal sealed class DeferredTransportFactory : IBrokerTransportFactory
{
private readonly Func<IBrokerTransportFactory> _factoryResolver;
private readonly string _transportName;
public DeferredTransportFactory(Func<IBrokerTransportFactory> factoryResolver, string transportName)
{
_factoryResolver = factoryResolver;
_transportName = transportName;
}
public string TransportName => _transportName;
public Task<IBrokerTransport> CreateTransportAsync(
IReadOnlyDictionary<string, string>? settings = null,
CancellationToken cancellationToken = default) =>
_factoryResolver().CreateTransportAsync(settings, cancellationToken);
}Optional helpers:
AddMessageHandler<THandler>()registers a typed handler and auto-subscribes it at startup.EnableOutbox(),EnableInbox(), andEnableReplay()opt into reliability features on the fluent builder.
See samples/BasicPublishSubscribe (InMemory) and samples/BrokerSwitching (RabbitMQ) for runnable examples.
dotnet restore EventMesh.slnx
dotnet build EventMesh.slnx --configuration Release
dotnet test EventMesh.slnx --configuration Releasedotnet run --project benchmarks/EventMesh.Benchmarks -c Release| Broker | Package | Status | Native strengths |
|---|---|---|---|
| RabbitMQ | EventMesh.Transport.RabbitMQ |
Compatibility-tested (beta) | Routing keys, priority, TTL, delayed exchange |
| Apache Kafka | EventMesh.Transport.Kafka |
Compatibility-tested (beta) | Partitions, consumer groups, offset replay |
| Redis Streams | EventMesh.Transport.RedisStreams |
Compatibility-tested (beta) | Consumer groups, pending/claim recovery |
| Azure Service Bus | EventMesh.Transport.AzureServiceBus |
Compatibility-tested (beta) | Sessions, transactions, native scheduling |
| AWS SQS | EventMesh.Transport.AmazonSqs |
Compatibility-tested (beta) | FIFO queues, delay queues, redrive DLQ |
| Google Pub/Sub | EventMesh.Transport.GooglePubSub |
Compatibility-tested (beta) | Ordering keys, seek-based replay |
| NATS JetStream | EventMesh.Transport.Nats |
Compatibility-tested (beta) | Durable consumers, sequence/time replay |
| InMemory | EventMesh.Transport.InMemory |
Stable for tests | Zero external dependencies |
See the Broker Capability Matrix for the full feature comparison and emulation behavior.
EventMesh/
├── src/ # Core libraries and transport adapters
├── tests/ # Unit, integration, and compatibility tests
├── benchmarks/ # BenchmarkDotNet performance suite
├── cli/ # eventmesh CLI tool
├── sdk/ # Plugin SDK
├── dashboard/ # React management UI (Milestone 10)
├── docker/ # Local development infrastructure
├── docs/ # Architecture docs and ADRs
└── .github/workflows/ # CI, release, and benchmark automation
| Document | Description |
|---|---|
| ARCHITECTURE.md | System design, layering, data/control plane |
| ROADMAP.md | Milestone plan and delivery status |
| CONTRIBUTING.md | Contribution guidelines and PR process |
| SECURITY.md | Security policy and vulnerability reporting |
| SUPPORT.md | Community and commercial support channels |
| CHANGELOG.md | Release history |
| docs/adr/ | Architecture Decision Records |
| Metric | Target |
|---|---|
| Throughput (InMemory) | 100,000+ messages/sec |
| P95 latency (InMemory) | < 5 ms |
| Test coverage | > 90% at GA |
Benchmark results are published on every release via the benchmark workflow.
EventMesh is released under the MIT License.
We welcome contributions. Please read CONTRIBUTING.md and our Code of Conduct before opening a pull request.