# What is the AppHost?

Aspire's AppHost is the code-first place where you declare your application's services and their relationships. Instead of managing scattered configuration files, you describe the architecture in code. Aspire then handles local orchestration so you can focus on building features.

## Defining your architecture

Consider a simple three-tier architecture where a frontend talks to an API, and the API relies on a database. Select an API language below to see the examples demonstrated in that language.

<PivotSelector
    title="Select your API platform"
    key="lang"
    marginTop="1"
    options={[
        { id: "csharp", title: "C#" },
        { id: "python", title: "Python" },
        { id: "nodejs", title: "Node.js" },
        { id: "go", title: "Go" },
        { id: "java", title: "Java" },
    ]}
/>

:::note
This three-tier architecture is just one example of how you can use Aspire. The AppHost is flexible and can model any distributed architecture, from microservices to serverless functions to multi-container apps. It works with any frontend, backend, database, or other resource—there are no limitations on the technologies you can use together.
:::

<Pivot id="csharp">

```mermaid
architecture-beta

  service db(logos:postgresql)[PostgreSQL]
  service api(logos:dotnet)[API service]
  service frontend(logos:react)[React frontend]

  api:R --> L:db
  frontend:R --> L:api
```

This architecture demonstrates a **.NET API** connecting to a **PostgreSQL database**, with a **React frontend** consuming the API. The .NET API uses ASP.NET Core and connects to PostgreSQL using Entity Framework or a connection string. The React frontend is built with Vite and communicates with the API over HTTP.

To build this architecture step-by-step, see the [Build your first app](/get-started/first-app/?lang=csharp) quickstart.

</Pivot>
<Pivot id="python">

```mermaid
architecture-beta

  service db(logos:postgresql)[PostgreSQL]
  service api(logos:python)[API service]
  service frontend(logos:react)[React frontend]

  api:R --> L:db
  frontend:R --> L:api
```

This architecture demonstrates a **Python API** (using FastAPI/Uvicorn) connecting to a **PostgreSQL database**, with a **React frontend** consuming the API. The Python API uses frameworks like FastAPI or Flask and connects to PostgreSQL using libraries like psycopg2 or SQLAlchemy. The React frontend is built with Vite and communicates with the API over HTTP.

To add this architecture to an existing Python-backed app, start with [Add Aspire to an existing app](/get-started/add-aspire-existing-app/) and then review the [Python integration](/integrations/frameworks/python/).
**Tip:** The Python integration is provided by the [Aspire.Hosting.Python](https://www.nuget.org/packages/Aspire.Hosting.Python) NuGet package. Learn more in the [Python integration](/integrations/frameworks/python/) documentation.

</Pivot>
<Pivot id="nodejs">

```mermaid
architecture-beta

  service db(logos:postgresql)[PostgreSQL]
  service api(logos:nodejs-icon)[API service]
  service frontend(logos:react)[React frontend]

  api:R --> L:db
  frontend:R --> L:api
```

This architecture demonstrates a **Node.js API** connecting to a **PostgreSQL database**, with a **React frontend** consuming the API. The Node.js API uses frameworks like Express or Fastify and connects to PostgreSQL using libraries like pg or Prisma. The React frontend is built with Vite and communicates with the API over HTTP.
**Tip:** The JavaScript/Node.js integration is provided by the [Aspire.Hosting.JavaScript](https://www.nuget.org/packages/Aspire.Hosting.JavaScript) NuGet package. Learn more in the [JavaScript integration](/integrations/frameworks/javascript/) documentation.

</Pivot>
<Pivot id="go">

```mermaid
architecture-beta

  service db(logos:postgresql)[PostgreSQL]
  service api(logos:go)[API service]
  service frontend(logos:react)[React frontend]

  api:R --> L:db
  frontend:R --> L:api
```

This architecture demonstrates a **Go API** connecting to a **PostgreSQL database**, with a **React frontend** consuming the API. The Go API uses the standard library's `net/http` package or frameworks like Gin or Echo and connects to PostgreSQL using libraries like pgx or database/sql. The React frontend is built with Vite and communicates with the API over HTTP.
**Tip:** The Go integration is provided by the [CommunityToolkit.Aspire.Hosting.Golang](https://www.nuget.org/packages/CommunityToolkit.Aspire.Hosting.Golang) NuGet package. Learn more in the [Go integration](/integrations/frameworks/go-apps/) documentation.

</Pivot>
<Pivot id="java">

```mermaid
architecture-beta

  service db(logos:postgresql)[PostgreSQL]
  service api(logos:java)[API service]
  service frontend(logos:react)[React frontend]

  api:R --> L:db
  frontend:R --> L:api
```

This architecture demonstrates a **Java API** (using Spring Boot) connecting to a **PostgreSQL database**, with a **React frontend** consuming the API. The Java API uses Spring Boot with Spring Data JPA and connects to PostgreSQL using JDBC or Spring Data. The React frontend is built with Vite and communicates with the API over HTTP.
**Tip:** The Java integration is provided by the [CommunityToolkit.Aspire.Hosting.Java](https://www.nuget.org/packages/CommunityToolkit.Aspire.Hosting.Java) NuGet package. Learn more in the [Java integration](/integrations/frameworks/java/) documentation.

</Pivot>

You can represent that architecture in an AppHost like this:

<Pivot id="csharp">
<SimpleAppHostCode lang="csharp">
  <div slot="csharp-content">
    <p>Uses <code>AddProject&lt;Projects.Api&gt;()</code> to reference a .NET project.</p>
  </div>
  <div slot="typescript-content">
    <p>Uses <code>addProject()</code> to reference the API project.</p>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="python">
<SimpleAppHostCode lang="python">
  <div slot="csharp-content">
    <p>Uses <code>AddUvicornApp()</code> with <code>WithUv()</code> for ASGI apps like FastAPI.</p>
  </div>
  <div slot="typescript-content">
    <p>Uses <code>addUvicornApp()</code> with <code>withUv()</code> for ASGI apps like FastAPI.</p>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="nodejs">
<SimpleAppHostCode lang="nodejs">
  <div slot="csharp-content">
    <p>Uses <code>AddNodeApp()</code> with <code>WithNpm()</code> for Node.js applications.</p>
  </div>
  <div slot="typescript-content">
    <p>Uses <code>addNodeApp()</code> with <code>withNpm()</code> for Node.js applications.</p>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="go">
<SimpleAppHostCode lang="go">
  <p>Uses <code>AddGolangApp()</code> for Go applications.</p>
</SimpleAppHostCode>
</Pivot>
<Pivot id="java">
<SimpleAppHostCode lang="java">
  <p>Uses <code>AddSpringApp()</code> for Spring Boot applications.</p>
</SimpleAppHostCode>
</Pivot>

The AppHost models your distributed application declaratively. Each code sample above shows the same three-tier architecture—**PostgreSQL database**, **API service**, and **React frontend**—but with different API implementations and, when available, different AppHost languages.

In all cases, the PostgreSQL database and React frontend remain identical. Aspire resource references establish dependencies between resources, and the app model ensures services start in the correct order.

Aspire presents the same, consistent model regardless of the language or framework used: services, resources, and the connections between them.

### Dissecting the AppHost code

Below we highlight the key parts of a typical AppHost to explain what each step does.

<Pivot id="csharp">
<SimpleAppHostCode lang="csharp" collapse={['3-16']}>
  <div slot="csharp-content">
    <p><strong>In the non-collapsed lines you:</strong></p>
    <ul>
      <li>Create the distributed application builder with <code>DistributedApplication.CreateBuilder(args)</code>.</li>
      <li>Call <code>Build()</code> to materialize the configuration into a runnable AppHost.</li>
      <li>Call <code>Run()</code> to start orchestration; services launch in dependency order.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>In the non-collapsed lines you:</strong></p>
    <ul>
      <li>Create the distributed application builder with <code>await createBuilder()</code>.</li>
      <li>Call <code>build()</code> to materialize the configuration into a runnable AppHost.</li>
      <li>Call <code>run()</code> to start orchestration; services launch in dependency order.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="python">
<SimpleAppHostCode lang="python" collapse={['3-17']}>
  <div slot="csharp-content">
    <p><strong>In the non-collapsed lines you:</strong></p>
    <ul>
      <li>Create the distributed application builder with <code>DistributedApplication.CreateBuilder(args)</code>.</li>
      <li>Call <code>Build()</code> to materialize the configuration into a runnable AppHost.</li>
      <li>Call <code>Run()</code> to start orchestration; services launch in dependency order.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>In the non-collapsed lines you:</strong></p>
    <ul>
      <li>Create the distributed application builder with <code>await createBuilder()</code>.</li>
      <li>Call <code>build()</code> to materialize the configuration into a runnable AppHost.</li>
      <li>Call <code>run()</code> to start orchestration; services launch in dependency order.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="nodejs">
<SimpleAppHostCode lang="nodejs" collapse={['3-17']}>
  <div slot="csharp-content">
    <p><strong>In the non-collapsed lines you:</strong></p>
    <ul>
      <li>Create the distributed application builder with <code>DistributedApplication.CreateBuilder(args)</code>.</li>
      <li>Call <code>Build()</code> to materialize the configuration into a runnable AppHost.</li>
      <li>Call <code>Run()</code> to start orchestration; services launch in dependency order.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>In the non-collapsed lines you:</strong></p>
    <ul>
      <li>Create the distributed application builder with <code>await createBuilder()</code>.</li>
      <li>Call <code>build()</code> to materialize the configuration into a runnable AppHost.</li>
      <li>Call <code>run()</code> to start orchestration; services launch in dependency order.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="go">
<SimpleAppHostCode lang="go" collapse={['3-17']}>
  <p><strong>In the non-collapsed lines you:</strong></p>
  <ul>
    <li>Create the distributed application builder with <code>DistributedApplication.CreateBuilder(args)</code>.</li>
    <li>Call <code>Build()</code> to materialize the configuration into a runnable AppHost.</li>
    <li>Call <code>Run()</code> to start orchestration; services launch in dependency order.</li>
  </ul>
</SimpleAppHostCode>
</Pivot>
<Pivot id="java">
<SimpleAppHostCode lang="java" collapse={['3-17']}>
  <p><strong>In the non-collapsed lines you:</strong></p>
  <ul>
    <li>Create the distributed application builder with <code>DistributedApplication.CreateBuilder(args)</code>.</li>
    <li>Call <code>Build()</code> to materialize the configuration into a runnable AppHost.</li>
    <li>Call <code>Run()</code> to start orchestration; services launch in dependency order.</li>
  </ul>
</SimpleAppHostCode>
</Pivot>

The AppHost is the blueprint for your distributed application—Aspire manages the rest.

#### Adding a PostgreSQL resource

With the builder ready, define resources and services. The snippet below shows how to add a PostgreSQL server and a database:

<Pivot id="csharp">
<SimpleAppHostCode lang="csharp" mark={{ range: '4-6' }} collapse={['8-17']}>
  <div slot="csharp-content">
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>AddPostgres("db")</code> registers a PostgreSQL container named <code>db</code>.</li>
      <li><code>.AddDatabase("appdata")</code> creates a database named <code>appdata</code> on that server.</li>
      <li><code>.WithDataVolume()</code> provisions a volume so data persists across container restarts.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>await builder.addPostgres("db")</code> registers a PostgreSQL server resource named <code>db</code>.</li>
      <li><code>.addDatabase("appdata")</code> adds the <code>appdata</code> database to that server.</li>
      <li><code>.withDataVolume()</code> enables persistent storage for the database container.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="python">
<SimpleAppHostCode lang="python" mark={{ range: '4-6' }} collapse={['8-18']}>
  <div slot="csharp-content">
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>AddPostgres("db")</code> registers a PostgreSQL container named <code>db</code>.</li>
      <li><code>.AddDatabase("appdata")</code> creates a database named <code>appdata</code> on that server.</li>
      <li><code>.WithDataVolume()</code> provisions a volume so data persists across container restarts.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>await builder.addPostgres("db")</code> registers a PostgreSQL server resource named <code>db</code>.</li>
      <li><code>.addDatabase("appdata")</code> adds the <code>appdata</code> database to that server.</li>
      <li><code>.withDataVolume()</code> enables persistent storage for the database container.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="nodejs">
<SimpleAppHostCode lang="nodejs" mark={{ range: '4-6' }} collapse={['8-18']}>
  <div slot="csharp-content">
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>AddPostgres("db")</code> registers a PostgreSQL container named <code>db</code>.</li>
      <li><code>.AddDatabase("appdata")</code> creates a database named <code>appdata</code> on that server.</li>
      <li><code>.WithDataVolume()</code> provisions a volume so data persists across container restarts.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>await builder.addPostgres("db")</code> registers a PostgreSQL server resource named <code>db</code>.</li>
      <li><code>.addDatabase("appdata")</code> adds the <code>appdata</code> database to that server.</li>
      <li><code>.withDataVolume()</code> enables persistent storage for the database container.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="go">
<SimpleAppHostCode lang="go" mark={{ range: '4-6' }} collapse={['8-18']}>
  <div>
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>AddPostgres("db")</code> registers a PostgreSQL container named <code>db</code>.</li>
      <li><code>.AddDatabase("appdata")</code> creates a database named <code>appdata</code> on that server.</li>
      <li><code>.WithDataVolume()</code> provisions a volume so data persists across container restarts.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="java">
<SimpleAppHostCode lang="java" mark={{ range: '4-6' }} collapse={['8-18']}>
  <div>
    <p><strong>How this works:</strong></p>
    <ul>
      <li><code>AddPostgres("db")</code> registers a PostgreSQL container named <code>db</code>.</li>
      <li><code>.AddDatabase("appdata")</code> creates a database named <code>appdata</code> on that server.</li>
      <li><code>.WithDataVolume()</code> provisions a volume so data persists across container restarts.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
**Tip:** To also keep the container running between AppHost restarts (avoiding slow startup), add `.WithLifetime(ContainerLifetime.Persistent)`. See [Persistent container lifetimes](/app-host/persistent-containers/) for details.

<LearnMore>
  Learn more about the official [PostgreSQL integration](/integrations/databases/postgres/postgres-get-started/).
</LearnMore>

#### Adding an API resource and declaring a dependency

Next, register the API service and wire it to the PostgreSQL resource:

<Pivot id="csharp">
<SimpleAppHostCode lang="csharp" mark={{ range: '9-11' }} collapse={['1-6', '13-17']}>
  <div slot="csharp-content">
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>AddProject&lt;Projects.Api&gt;("api")</code> registers the API project as a service named <code>api</code>.</li>
      <li><code>WithReference(postgres)</code> injects connection details into the API configuration.</li>
      <li><code>WaitFor(postgres)</code> delays startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>addProject("api", "../api/Api.csproj", "https")</code> registers the API project as a service named <code>api</code>.</li>
      <li><code>withReference(postgres)</code> wires the database dependency into the API resource.</li>
      <li><code>waitFor(postgres)</code> delays startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="python">
<SimpleAppHostCode lang="python" mark={{ range: '9-12' }} collapse={['1-6', '14-18']}>
  <div slot="csharp-content">
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>AddUvicornApp("api", "../api", "main:app")</code> registers a Uvicorn-based Python app named <code>api</code>.</li>
      <li><code>WithUv()</code> configures the app to use the <a href="https://docs.astral.sh/uv/">uv</a> package manager.</li>
      <li><code>WithReference(postgres)</code> injects connection details into the API configuration.</li>
      <li><code>WaitFor(postgres)</code> delays startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>addUvicornApp("api", "../api", "main:app")</code> registers a Uvicorn-based Python app named <code>api</code>.</li>
      <li><code>withUv()</code> enables <a href="https://docs.astral.sh/uv/">uv</a>-based dependency management.</li>
      <li><code>withReference(postgres)</code> injects the database connection details.</li>
      <li><code>waitFor(postgres)</code> delays startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="nodejs">
<SimpleAppHostCode lang="nodejs" mark={{ range: '9-12' }} collapse={['1-6', '14-18']}>
  <div slot="csharp-content">
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>AddNodeApp("api", "../api", "server.js")</code> registers a Node.js app named <code>api</code>.</li>
      <li><code>WithNpm()</code> configures the app to use npm for dependency installation.</li>
      <li><code>WithReference(postgres)</code> injects connection details into the API configuration.</li>
      <li><code>WaitFor(postgres)</code> delays startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>addNodeApp("api", "../api", "server.js")</code> registers a Node.js app named <code>api</code>.</li>
      <li><code>withNpm()</code> configures npm-based dependency installation.</li>
      <li><code>withReference(postgres)</code> injects the database connection details.</li>
      <li><code>waitFor(postgres)</code> delays startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="go">
<SimpleAppHostCode lang="go" mark={{ range: '9-12' }} collapse={['1-6', '14-18']}>
  <div>
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>AddGolangApp("api", "../api")</code> registers a Go app as a service named <code>api</code>.</li>
      <li><code>WithHttpEndpoint(env: "PORT")</code> configures the port and sets the <code>PORT</code> environment variable.</li>
      <li><code>WithReference(postgres)</code> injects connection details into the API configuration.</li>
      <li><code>WaitFor(postgres)</code> delays the API startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="java">
<SimpleAppHostCode lang="java" mark={{ range: '9-12' }} collapse={['1-6', '14-18']}>
  <div>
    <p><strong>What this does:</strong></p>
    <ul>
      <li><code>AddSpringApp("api", "../api", "otel.jar")</code> registers a Spring Boot app named <code>api</code>.</li>
      <li><code>WithHttpEndpoint(port: 8080)</code> exposes the Spring Boot app on port <code>8080</code>.</li>
      <li><code>WithReference(postgres)</code> injects connection details into the API configuration.</li>
      <li><code>WaitFor(postgres)</code> delays the API startup until PostgreSQL is healthy.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>

Now that the `api` service is defined, you can attach the frontend.

#### Adding a frontend resource

Register the frontend project, declare its dependency on the API, and let the AppHost provide the API address automatically.
**Note:** This example uses a Node.js (React) frontend, but Aspire treats frontends as executable services—any language or framework works.

<Pivot id="csharp">
<SimpleAppHostCode lang="csharp" mark={{ range: '14-16' }} collapse={['1-11']}>
  <div slot="csharp-content">
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>AddViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>WithHttpEndpoint(env: "PORT")</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>WithReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>addViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>withHttpEndpoint({'{'} env: "PORT" {'}'})</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>withReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="python">
<SimpleAppHostCode lang="python" mark={{ range: '15-17' }} collapse={['1-12']}>
  <div slot="csharp-content">
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>AddViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>WithHttpEndpoint(env: "PORT")</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>WithReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>addViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>withHttpEndpoint({'{'} env: "PORT" {'}'})</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>withReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="nodejs">
<SimpleAppHostCode lang="nodejs" mark={{ range: '15-17' }} collapse={['1-12']}>
  <div slot="csharp-content">
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>AddViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>WithHttpEndpoint(env: "PORT")</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>WithReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
  <div slot="typescript-content">
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>addViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>withHttpEndpoint({'{'} env: "PORT" {'}'})</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>withReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="go">
<SimpleAppHostCode lang="go" mark={{ range: '15-17' }} collapse={['1-12']}>
  <div>
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>AddViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>WithHttpEndpoint(env: "PORT")</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>WithReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>
<Pivot id="java">
<SimpleAppHostCode lang="java" mark={{ range: '15-17' }} collapse={['1-12']}>
  <div>
    <p><strong>Key points:</strong></p>
    <ul>
      <li><code>AddViteApp("frontend", "../frontend")</code> registers the frontend as a service named <code>frontend</code>.</li>
      <li><code>WithHttpEndpoint(env: "PORT")</code> exposes the app and lets the <code>PORT</code> environment variable control the listener.</li>
      <li><code>WithReference(api)</code> injects the API base address into the frontend configuration.</li>
    </ul>
  </div>
</SimpleAppHostCode>
</Pivot>

In short: define the backend first (DB → API), then point the UI at the API. The AppHost captures the dependency graph, connection flows, and startup order.

#### Configuration and networking

These dependencies and connections are automatically managed by Aspire. The AppHost generates configuration values like connection strings and endpoints, injecting them into services as needed. In the AppHost when you add resources, you name them (e.g., `db`, `api`, `frontend`); Aspire uses these names for DNS resolution, so services can communicate using predictable addresses. Consuming services also rely on these names for configuration injection.

<Pivot id="csharp">

```mermaid
architecture-beta

  service db(logos:postgresql)[pg]
  service epr(iconoir:server-connection)[Endpoint Reference]
  service api(logos:dotnet)[api]
  service ctr(iconoir:server-connection)[Connection String Reference]
  service frontend(logos:react)[frontend]

  db:L <-- R:ctr
  ctr:L <-- R:api
  api:L <-- R:epr
  epr:L <-- R:frontend
```

The .NET API receives a **ConnectionStringReference** from PostgreSQL and publishes an **EndpointReference** that the React frontend consumes. This creates a clear dependency chain: `PostgreSQL → .NET API → React frontend`.

</Pivot>
<Pivot id="python">

```mermaid
architecture-beta

  service db(logos:postgresql)[pg]
  service epr(iconoir:server-connection)[Endpoint Reference]
  service api(logos:python)[api]
  service ctr(iconoir:server-connection)[Connection String Reference]
  service frontend(logos:react)[frontend]

  db:L <-- R:ctr
  ctr:L <-- R:api
  api:L <-- R:epr
  epr:L <-- R:frontend
```

The Python API receives a **ConnectionStringReference** from PostgreSQL and publishes an **EndpointReference** that the React frontend consumes. This creates a clear dependency chain: `PostgreSQL → Python API → React frontend`.

</Pivot>
<Pivot id="nodejs">

```mermaid
architecture-beta

  service db(logos:postgresql)[pg]
  service epr(iconoir:server-connection)[Endpoint Reference]
  service api(logos:nodejs-icon)[api]
  service ctr(iconoir:server-connection)[Connection String Reference]
  service frontend(logos:react)[frontend]

  db:L <-- R:ctr
  ctr:L <-- R:api
  api:L <-- R:epr
  epr:L <-- R:frontend
```

The Node.js API receives a **ConnectionStringReference** from PostgreSQL and publishes an **EndpointReference** that the React frontend consumes. This creates a clear dependency chain: `PostgreSQL → Node.js API → React frontend`.

</Pivot>
<Pivot id="go">

```mermaid
architecture-beta

  service db(logos:postgresql)[pg]
  service epr(iconoir:server-connection)[Endpoint Reference]
  service api(logos:go)[api]
  service ctr(iconoir:server-connection)[Connection String Reference]
  service frontend(logos:react)[frontend]

  db:L <-- R:ctr
  ctr:L <-- R:api
  api:L <-- R:epr
  epr:L <-- R:frontend
```

The Go API receives a **ConnectionStringReference** from PostgreSQL and publishes an **EndpointReference** that the React frontend consumes. This creates a clear dependency chain: `PostgreSQL → Go API → React frontend`.

</Pivot>
<Pivot id="java">

```mermaid
architecture-beta

  service db(logos:postgresql)[pg]
  service epr(iconoir:server-connection)[Endpoint Reference]
  service api(logos:java)[api]
  service ctr(iconoir:server-connection)[Connection String Reference]
  service frontend(logos:react)[frontend]

  db:L <-- R:ctr
  ctr:L <-- R:api
  api:L <-- R:epr
  epr:L <-- R:frontend
```

The Java API receives a **ConnectionStringReference** from PostgreSQL and publishes an **EndpointReference** that the React frontend consumes. This creates a clear dependency chain: `PostgreSQL → Java API → React frontend`.

</Pivot>

**How these resources communicate**

1. `pg` publishes a `ConnectionStringReference` (host, port, database, user, password)—a strongly typed bundle Aspire understands.
1. `api` declares a dependency on that reference; Aspire injects the connection string into its config with a unique configuration-flow process that injects settings values, including secrets, parameters, and connection strings for both local runs and deployments.
1. `api` then publishes an `EndpointReference` (its base URL) after its HTTP endpoint is allocated.
1. `frontend` depends on that endpoint; Aspire injects the API base URL so no hard-coded addresses are needed.
**Tip:** Aspire replaces ad-hoc run scripts, scattered environment variables, and fragile copy-pasted connection strings with a single, declarative source of truth. By modeling services, resources, and their dependencies in code, it delivers typed configuration (endpoints, credentials, connection strings) directly where needed—reducing setup drift, accelerating onboarding, and letting you evolve the architecture without rewriting glue.

## How the AppHost works

When you run the AppHost, Aspire performs these core responsibilities:

1. **Service discovery**: Aspire discovers services and resources declared in the AppHost.
1. **Dependency resolution**: Services start in the correct order based on declared dependencies.
1. **Configuration injection**: Connection strings, endpoints, and other config values are injected automatically.
1. **Health monitoring**: Aspire observes service health and can restart services when necessary.

<LearnMore>
  Dive deeper into Aspire's orchestration and the [Resource model](/architecture/resource-model/).
</LearnMore>

## AppHost structure

The template AppHost is structured in the following ways:

- **AspireApp.AppHost**
        - apphost.cs  dev-time orchestrator
        - apphost.run.json
    - **AspireApp.AppHost**
        - Properties
          - launchSettings.json
        - appsettings.Development.json
        - appsettings.json
        - AspireApp.AppHost.csproj
        - AppHost.cs  dev-time orchestrator
    - **my-apphost/**
        - .modules/  Generated SDK
        - apphost.ts  dev-time orchestrator
        - aspire.config.json
        - package.json
        - tsconfig.json
    ## AppHost lifecycle events

You can hook into lifecycle events to run custom logic during startup and resource allocation.

1. `BeforeStartEvent`: Raised before the AppHost begins starting services.
1. `AfterEndpointsAllocatedEvent`: Raised after endpoints are allocated for services.
1. `AfterResourcesCreatedEvent`: Raised after all resources are created.

<LearnMore>
  For finer-grained lifecycle control, see the [well-known lifecycle events](/architecture/resource-model/#well-known-lifecycle-events).
</LearnMore>

## Best practices

- Keep the AppHost minimal to start; add complexity only as required.
- Define explicit dependencies with `.WithReference(...)` to make wiring obvious.
- Use separate configurations for development, testing, and production.
- Pick clear, descriptive names for resources to make debugging and logging easier.