The state of Aspire in 2026

📅 11 May 2026 ⏱️ 15 min 💾 Code 🎥 YouTube 🇪🇸 Spanish Version 💬 0

A couple of years ago I published an introduction to .NET Aspire when it had just been released. If you go back and read that post today, you will see just how much it has changed. Back then it was an orchestrator to spin up two APIs and a Redis locally, all super tightly coupled to .NET, with a dashboard that was almost an experiment.

 

Aspire in 2026 looks nothing like that anymore. It is no longer "a cool utility for local .NET microservices". It is an orchestration platform that supports multiple languages, with a serious telemetry system, native integrations with practically any resource you use in production and, most importantly for me, it is the tool I work with every single day in my job. It is not a demo toy, it is what I fire up whenever I work on any project at the company.

 

 

Let's take a look at where it stands today and why you should be working with it.

 

 

1 - Where Aspire fits into development in 2026

 

If you have never touched Aspire, your way of developing applications is probably importing a solution with five services, a database, a Redis, some queueing system like RabbitMQ, and then each service in a different programming language so you can have a React front end.

 

In these situations there are usually two options: either you have everything installed natively on your machine, or you have everything in containers with docker-compose, which is relatively hard to maintain because there is a lot of configuration involved and all that stuff. Everything explained in a README with 250 million steps.

 

This is where Aspire comes in, combining all that boilerplate into a single project. Aspire is a normal C# application that, when started, launches a supervision process that manages the lifecycle of every resource it needs, spins up containers, starts processes, injects variables, already has service discovery built in, and includes a dashboard that brings everything together and shows it all very nicely using OpenTelemetry.

When you configure each service, you can specify who depends on whom, so everything is brought up in sync and in the right order.

 

 

1.1 - Configuration and orchestration as code

 

Absolutely everything is configured inside the apphost, and the truth is the structure does remind you of what docker-compose used to be, but of course, we are building infrastructure, so it is obviously going to look similar. This is what it looks like in our example:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithPgAdmin();
var productsDb = postgres.AddDatabase("productsdb");

var cache = builder.AddRedis("cache")
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithRedisInsight();

var messaging = builder.AddRabbitMQ("messaging")
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithManagementPlugin();

var storage = builder.AddAzureStorage("storage")
    .RunAsEmulator(e => e.WithLifetime(ContainerLifetime.Persistent).WithDataVolume());
var blobs = storage.AddBlobs("blobs");

var api = builder.AddProject<Projects.AspireApp_Api>("api")
    .WithReference(productsDb)
    .WaitFor(productsDb)
    .WithReference(cache)
    .WaitFor(cache)
    .WithReference(blobs)
    .WaitFor(blobs)
    .WithExternalHttpEndpoints();

builder.AddNpmApp("frontend", "../react-app")
    .WithReference(api)
    .WaitFor(api)
    .WithHttpEndpoint(env: "PORT")
    .WithExternalHttpEndpoints();

builder.AddExecutable("outbox-worker", "go", "../go-worker", "run", ".")
    .WithReference(productsDb)
    .WaitFor(productsDb)
    .WithReference(messaging)
    .WaitFor(messaging);

builder.Build().Run();

We have a C# API and a React front end. The use case is simple, just reading and listing products, but we also have a Redis cache, the database holding all the information, along with blob storage for the images and RabbitMQ for events to other domains through the outbox pattern, plus a worker written in Go that reads every two seconds and publishes the event to RabbitMQ.

 

NOTE: If you want to learn more about event systems, consistency or distributed systems in general, remember that I have my book for sale, "Building Distributed Systems", where you will learn about these topics and many more, all relevant to the working world. You can find it here -> https://www.netmentor.es/libros/construyendo-sistemas-distribuidos  

 

And in the same way that you can run everything on your local machine, you can also do it in a pipeline for tests or generate manifests for Kubernetes or docker-compose to be used in production.

 

 

1.2 - Aspire is no longer just .NET

 

You may have noticed in the previous section that we are not configuring only C# applications, but also a Go background worker and the front end in JavaScript. But this setup is not limited to just having applications configured. Aspire itself can be configured in TypeScript if your whole stack is in JavaScript, and not only that, there is also a kind of semi-official confirmation that it will be available in Python, Rust, Go and Java!

That is huge news for developers in those ecosystems because they are no longer forced to learn or maintain C# for a single infrastructure file.

 

 

1.3 - Integration with Azure infrastructure

 

I am not especially an Azure guy, I say it openly, even though I work with it. But you have to admit that if your production environment lives in Azure, the native integrations are amazing.

 

In the example we are working with in this blog, that means BlobStorage.

Let's focus on the API side, where we have it configured like this:

builder.AddAzureBlobServiceClient("blobs");

 

If you go to the library that implements the AddAzureBlobServiceClient method, it is in the Aspire library: Aspire.Azure.Storage.Blobs. And with this exact same code, we connect to blob storage running locally through Azurite and to Azure cloud just by changing the connection string once it is deployed. That is amazing. Obviously, if you do not work with Azure, you just ignore it, but if you do work with Azure, it is an obvious advantage.

 

 

2 - Telemetry built into Aspire by default

 

This is a crucial point, maybe one of the most important ones, because everything started from the Aspire AppHost emits telemetry with logs, traces and metrics to the dashboard's otel endpoint without configuring anything at all, right out of the box.

 

You might think, sure, sounds great, but it is a local tool. It does not stop there because by using OpenTelemetry, all you have to do is change the endpoint to your production one so that the exact same telemetry points directly to your production server.

Telemetry, or more specifically distributed traces, can be one of the fundamental pillars every developer has to grow in their career. Being able to identify a full trace of a request or a user action. Without distributed traces it is practically impossible to see what is happening. In Aspire, you have it all in the dashboard, linked and related right out of the box.

 

 

3 - When NOT to use Aspire

 

Before wrapping up, it is worth mentioning that even though Aspire is an amazing technology, especially in companies, it may not be what you always want to use. It is not a one-size-fits-all solution that will fix everything, there are situations where it does not fit.

For example, it works wonderfully locally, but you cannot expect the AppHost to run in production.

 

It is extra work, more configuration, more files, or more complications in general, so if your project only has a database and an API, it is probably not worth it. It starts paying off when you have several services or applications that you depend on.

 

The dependency on C# or TypeScript is obvious. If you want to use Aspire right now, you have to use one of those two languages and, although they have promised more, they still have to arrive. For now it is limited to those languages or environments, so the vast majority of people still do not know Aspire, which I am not sure is good or bad.

 

 

Conclusion

 

My first impressions of Aspire were not the best. They were fine, but nothing special. During these more than two years it has evolved massively, and that is worth mentioning.

 

I recommend everyone give it another chance. The distance between what it was back then and what it is today is enormous: serious telemetry, integrations with almost any resource, a mature dashboard, and a deployment model that is starting to make sense.

 

Personally, I use Aspire daily at work, and this post is simply here to show those who are not using it what they are missing out on. 

This post was translated from Spanish. You can see the original one here.
If there is any problem you can add a comment below or contact me in the website's contact form.


💬 Comments