Introduction
.NET Aspire started with a strong focus on distributed .NET applications, but modern systems rarely use only one programming language.
A production application may contain a .NET API, a Java service, a Rust worker, a Node.js frontend, and several infrastructure dependencies. The challenge is not necessarily how to run each technology independently. The harder problem is coordinating them as one distributed application during development.
Aspire 13.6 expands the hosting model with support for Java and Rust applications, allowing developers to describe these services alongside .NET projects and infrastructure resources.
This makes the AppHost more useful as an application composition layer rather than a .NET-only launcher.
What Is the Aspire Hosting Model?
The Aspire hosting model allows developers to describe the resources that make up a distributed application.
A simplified application might contain:
AppHost
|
+---- .NET API
|
+---- Java Service
|
+---- Rust Worker
|
+---- PostgreSQL
|
+---- Redis
Instead of starting every component manually, the AppHost defines how the resources relate to each other.
The Aspire tooling can then provide a unified development experience around those resources.
Why Multi-Language Hosting Matters
Real-world systems often evolve over time.
A company might already have a Java service that handles payments while newer APIs are being developed with .NET.
Another team might use Rust for a high-performance worker.
Without a common application model, developers may need separate startup scripts:
Terminal 1 -> .NET API
Terminal 2 -> Java Service
Terminal 3 -> Rust Worker
Terminal 4 -> PostgreSQL
Terminal 5 -> Redis
That approach works for small systems but becomes increasingly difficult to manage.
A composed Aspire application can instead describe the system centrally:
Aspire AppHost
|
+--------------+--------------+
| | |
.NET Java Rust
| | |
+--------------+--------------+
|
Infrastructure
PostgreSQL / Redis
The programming language becomes an implementation detail of an individual resource rather than a limitation of the application model.
Java and Rust as Application Resources
The important architectural change is that Java and Rust applications can participate in the same resource graph as .NET projects.
Conceptually:
Application
|
+---- api
+---- payment-service
+---- worker
|
+---- postgres
+---- cache
The resources can have different implementations:
api -> .NET
payment-service -> Java
worker -> Rust
postgres -> PostgreSQL
cache -> Redis
The AppHost becomes the place where these components are composed.
Why Use Aspire Instead of Separate Startup Scripts?
A distributed application has more than startup commands.
Developers also need to understand:
Which services are running
Which endpoints are available
Which dependencies are required
Which environment variables are configured
Which service depends on another
Which component is unhealthy
Where logs are located
A centralized application model can make these relationships easier to see.
For example:
Java Payment Service
|
+---- PostgreSQL
|
+---- Redis
.NET API
|
+---- Java Payment Service
Rust Worker
|
+---- PostgreSQL
The dependency graph becomes part of the development environment.
Hosting a Java Application
A Java application can be represented as an application resource in the Aspire AppHost.
The exact configuration depends on the application's build and runtime model.
For example, a Java service may be built using Maven or Gradle:
payment-service/
pom.xml
src/
or:
payment-service/
build.gradle
src/
The AppHost can then coordinate the Java service alongside the other application resources.
The Java application does not need to be rewritten in .NET.
That distinction is important.
Aspire provides application composition and orchestration capabilities. It does not convert one programming language into another.
Hosting a Rust Application
Rust is useful for services where developers need predictable resource usage, native performance, or low-level control.
A Rust project might look like:
worker/
Cargo.toml
src/
main.rs
The worker can participate in the same distributed application:
Aspire AppHost
|
+---- .NET API
|
+---- Java Service
|
+---- Rust Worker
The Rust process remains a Rust application.
Aspire provides the surrounding development composition rather than changing the implementation language.
Connecting Services Together
A multi-language application becomes useful when services can communicate through well-defined contracts.
For example:
.NET API
|
| HTTP
v
Java Payment Service
|
| PostgreSQL
v
Database
A Rust worker might consume messages separately:
.NET API
|
v
Message Broker
|
v
Rust Worker
The application model can describe these relationships.
This is more useful than simply starting three processes because the development environment understands that they form one application.
Service Discovery and Configuration
Distributed applications should avoid hardcoding local addresses whenever possible.
For example, avoid building development configuration around:
http://localhost:5007
http://localhost:8081
http://localhost:9000
These ports can change.
A composed application can instead provide service references and connection information through the application model.
The conceptual flow is:
AppHost
|
+---- Service A
|
+---- Service B
|
v
Resolved Endpoint
This reduces the amount of manual configuration developers need to maintain.
Environment Variables Across Languages
Different programming languages consume configuration differently.
A .NET application might use:
ConnectionStrings__Database
A Java application might read:
DATABASE_URL
A Rust application might use:
DATABASE_URL
RUST_LOG
The application composition layer can provide the required environment configuration while each service remains responsible for interpreting it according to its own runtime conventions.
This is an important separation:
Aspire
|
+---- Provides configuration
|
+---- Provides resource relationships
|
v
Application
|
+---- Interprets configuration
Database Dependencies
Suppose the application contains a PostgreSQL resource:
PostgreSQL
|
+---- .NET API
+---- Java Service
+---- Rust Worker
Each application may use the database differently.
The .NET service may use Entity Framework Core.
The Java service may use JDBC or another PostgreSQL driver.

Join the conversation! Your thoughts help the community grow.