# Aspire SDK for distributed apps

The Aspire SDK is intended for [AppHost projects](/get-started/app-host/), which serve as the orchestrator for Aspire applications. These projects are designated by their usage of the `Aspire.AppHost.Sdk` in the project file. The SDK provides features that simplify the development of Aspire apps.

The [📦 Aspire.AppHost.Sdk](https://www.nuget.org/packages/Aspire.AppHost.Sdk) is used for building Aspire apps.

The `Aspire.AppHost.Sdk` is defined in the top-level `Project` node's `Sdk` attribute:

```xml title='XML — *.csproj file' {1}
<Project Sdk="Aspire.AppHost.Sdk/13.1">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net10.0</TargetFramework>
        <!-- Omitted for brevity -->
    </PropertyGroup>

    <!-- Omitted for brevity -->
</Project>
```

The `Aspire.AppHost.Sdk` is defined in a file-based app's source file using the `#:sdk` directive:

```csharp title='C# — file-based app' {1}
#:sdk Aspire.AppHost.Sdk@13.3.0

var builder = DistributedApplication.CreateBuilder(args);

// Omitted for brevity
```

The preceding example defines the top-level SDK as `Aspire.AppHost.Sdk`. The project also references the [📦 Aspire.Hosting.AppHost](https://www.nuget.org/packages/Aspire.Hosting.AppHost) package which brings in a number of Aspire-related dependencies.

## SDK Features

The Aspire SDK provides several key features.

### Project references

Each `ProjectReference` in the AppHost project isn't treated as standard project references. Instead, they enable the AppHost to execute these projects as part of its orchestration. Each project reference triggers a generator to create a `class` that represents the project as an `IProjectMetadata`. This metadata is used to populate the named projects in the generated `Projects` namespace. When you call the `AddProject` API, the `Projects` namespace is used to reference the project—passing the generated class as a generic-type parameter.

:::tip
To prevent a project from being treated as an Aspire resource in the AppHost, set the `IsAspireProjectResource` attribute on the `ProjectReference` element to `false`, as shown in the following example:

```xml
<ProjectReference Include="..\MyProject\MyProject.csproj" IsAspireProjectResource="false" />
```

Otherwise, by default, the `ProjectReference` is treated as Aspire project resource.
:::

<LearnMore>
For the end-to-end `AddProject` workflow, see [Project resources](/integrations/dotnet/project-resources/).
</LearnMore>

#### Customizing generated project names

When you reference a project in the AppHost, the Aspire SDK generates a strongly-typed class in the `Projects` namespace. By default, the generated class name is based on the project's name. However, if you have multiple projects with the same name or want to customize the generated type name, you can use the `AspireProjectMetadataTypeName` attribute.

For example, if you have two microservices with the same project name (like `Presentation.Api`), you can differentiate them by setting custom names:

```xml
<ItemGroup>
  <ProjectReference Include="..\Microservice1\Presentation.Api\Presentation.Api.csproj"
                    AspireProjectMetadataTypeName="MicroService1" />
  <ProjectReference Include="..\Microservice2\Presentation.Api\Presentation.Api.csproj"
                    AspireProjectMetadataTypeName="MicroService2" />
</ItemGroup>
```

This generates `Projects.MicroService1` and `Projects.MicroService2` classes, allowing you to reference each project distinctly in your AppHost:

```csharp title="AppHost.cs"
var microservice1 = builder.AddProject<Projects.MicroService1>("micro1");
var microservice2 = builder.AddProject<Projects.MicroService2>("micro2");
```

### Orchestrator dependencies

The Aspire SDK dynamically adds references to the [Aspire Dashboard](/dashboard/overview/) and other AppHost dependencies, such as the developer control plane (DCP) packages. These dependencies are specific to the platform that the AppHost is built on.

When the AppHost project runs, the orchestrator relies on these dependencies to provide the necessary functionality to the AppHost. For more information, see [Aspire orchestration overview](/get-started/app-host/).

### Use the Aspire CLI bundle for orchestration dependencies

:::caution[Preview feature]
`AspireUseCliBundle` is a preview opt-in that smooths the transition to CLI-bundle-based orchestration dependencies before they become the default.
:::

Today, the Aspire SDK restores the binaries for these dependencies from platform-specific NuGet packages, so the versions that run with your AppHost are tied to package restore.

Aspire is moving toward using the installed **Aspire CLI bundle** as the source for those orchestration dependencies. With this model, those binaries update when you update the Aspire CLI through [`aspire update --self`](/reference/cli/commands/aspire-update/) instead of being tied to RID-specific `Aspire.Hosting.Orchestration.*` and `Aspire.Dashboard.Sdk.*` package references in each AppHost project.

Set `AspireUseCliBundle` to `true` to opt in during the transition before this behavior becomes the default.

When `AspireUseCliBundle` is `true`:

- `Aspire.AppHost.Sdk` still sets AppHost properties and adds the implicit `Aspire.Hosting.AppHost` package.
- Your AppHost uses the DCP and Dashboard versions installed with the Aspire CLI.
- At build time, the SDK resolves the DCP and Dashboard executables in this priority order:
1. Explicit `AspireCliBundlePath` / `AspireCliPath` properties in the project file.
2. The `aspire` executable on `PATH`.
- If the bundle cannot be found, the build emits error `ASPIRE009` with a message directing you to [get.aspire.dev](https://get.aspire.dev) to install the Aspire CLI.

#### Enable the opt-in

Set `AspireUseCliBundle` in your AppHost `.csproj`:

```xml title="MyApp.AppHost.csproj"
<PropertyGroup>
  <AspireUseCliBundle>true</AspireUseCliBundle>
</PropertyGroup>
```

:::note[Advanced scenario: Override the bundle path]
Most apps don't need to set the CLI bundle path. If the Aspire CLI isn't on `PATH`, provide an explicit path using `AspireCliBundlePath` (path to the CLI bundle directory) or `AspireCliPath` (path to the `aspire` executable):

```xml title="MyApp.AppHost.csproj"
<PropertyGroup>
  <AspireUseCliBundle>true</AspireUseCliBundle>
  <!-- Either set the path to the aspire executable: -->
  <AspireCliPath>/usr/local/bin/aspire</AspireCliPath>
  <!-- Or set the path to the unpacked CLI bundle directory: -->
  <!-- <AspireCliBundlePath>/path/to/aspire/bundle</AspireCliBundlePath> -->
</PropertyGroup>
```
:::

#### Running with aspire run or aspire start

When you start an opted-in AppHost using `aspire run` or `aspire start`, the CLI automatically passes the resolved bundle paths through the `ASPIRE_DCP_PATH` and `ASPIRE_DASHBOARD_PATH` environment variables.