diff --git a/src/frontend/config/sidebar/docs.topics.ts b/src/frontend/config/sidebar/docs.topics.ts
index fb57780ed..d8bbf7c9c 100644
--- a/src/frontend/config/sidebar/docs.topics.ts
+++ b/src/frontend/config/sidebar/docs.topics.ts
@@ -271,6 +271,7 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = {
},
{
label: 'Build your first app',
+ collapsed: false,
translations: {
da: 'Byg din første app',
de: 'Erstellen Sie Ihre erste App',
@@ -289,29 +290,42 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = {
uk: 'Створіть свій перший додаток',
'zh-CN': '构建您的第一个应用',
},
- slug: 'get-started/first-app',
- badge: {
- text: 'Quickstart',
- variant: 'tip',
- translations: {
- da: 'Hurtigstart',
- de: 'Schnellstart',
- en: 'Quickstart',
- es: 'Inicio rápido',
- fr: 'Démarrage rapide',
- hi: 'त्वरित आरंभ',
- id: 'Memulai Cepat',
- it: 'Avvio rapido',
- ja: 'クイックスタート',
- ko: '빠른 시작',
- 'pt-BR': 'Início Rápido',
- 'pt-PT': 'Início Rápido',
- ru: 'Быстрый старт',
- tr: 'Hızlı Başlangıç',
- uk: 'Швидкий старт',
- 'zh-CN': '快速开始',
+ items: [
+ {
+ label: 'Overview',
+ slug: 'get-started/first-app',
+ badge: {
+ text: 'Quickstart',
+ variant: 'tip',
+ translations: {
+ da: 'Hurtigstart',
+ de: 'Schnellstart',
+ en: 'Quickstart',
+ es: 'Inicio rápido',
+ fr: 'Démarrage rapide',
+ hi: 'त्वरित आरंभ',
+ id: 'Memulai Cepat',
+ it: 'Avvio rapido',
+ ja: 'クイックスタート',
+ ko: '빠른 시작',
+ 'pt-BR': 'Início Rápido',
+ 'pt-PT': 'Início Rápido',
+ ru: 'Быстрый старт',
+ tr: 'Hızlı Başlangıç',
+ uk: 'Швидкий старт',
+ 'zh-CN': '快速开始',
+ },
+ },
},
- },
+ {
+ label: 'C# AppHost',
+ slug: 'get-started/first-app-csharp-apphost',
+ },
+ {
+ label: 'TypeScript AppHost',
+ slug: 'get-started/first-app-typescript-apphost',
+ },
+ ],
},
{
label: 'Deploy your first app',
@@ -358,6 +372,7 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = {
},
{
label: 'Aspireify an existing app',
+ collapsed: false,
translations: {
da: 'Aspireify en eksisterende app',
de: 'Eine bestehende App Aspireify',
@@ -376,7 +391,20 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = {
uk: 'Aspireify наявний застосунок',
'zh-CN': '对现有应用进行 Aspireify',
},
- slug: 'get-started/add-aspire-existing-app',
+ items: [
+ {
+ label: 'Overview',
+ slug: 'get-started/add-aspire-existing-app',
+ },
+ {
+ label: 'C# AppHost',
+ slug: 'get-started/add-aspire-existing-app-csharp-apphost',
+ },
+ {
+ label: 'TypeScript AppHost',
+ slug: 'get-started/add-aspire-existing-app-typescript-apphost',
+ },
+ ],
},
{
label: 'Use AI coding agents',
diff --git a/src/frontend/src/content/docs/get-started/add-aspire-existing-app-csharp-apphost.mdx b/src/frontend/src/content/docs/get-started/add-aspire-existing-app-csharp-apphost.mdx
new file mode 100644
index 000000000..d3df44ee5
--- /dev/null
+++ b/src/frontend/src/content/docs/get-started/add-aspire-existing-app-csharp-apphost.mdx
@@ -0,0 +1,955 @@
+---
+title: "Aspireify an existing app with a C# AppHost"
+description: "Learn how to add Aspire orchestration to an existing application by using a C# AppHost."
+prev: false
+next: false
+---
+
+import { Aside, Steps, FileTree, Tabs, TabItem } from '@astrojs/starlight/components';
+import { Kbd } from 'starlight-kbd/components'
+import LearnMore from '@components/LearnMore.astro';
+import InstallPackage from '@components/InstallPackage.astro';
+import PivotSelector from '@components/PivotSelector.astro';
+import Pivot from '@components/Pivot.astro';
+
+
+
+
+This guide shows you how to add Aspire orchestration to an existing application while using a C# AppHost (`AppHost.cs` or `apphost.cs`). Choose the app stack you're bringing to Aspire, then initialize the AppHost, register your resources, and run everything locally with Aspire.
+
+:::note[Definition]{icon="approve-check-circle"}
+**Aspireify** (verb): To transform an existing application into a distributed, observable, and orchestrated system by adding Aspire—no cape required, just a few commands!
+:::
+
+## Why add Aspire to an existing app?
+
+As distributed applications grow, coordinating multiple services becomes a tangled web of configuration files, hard-coded URLs, and fragile startup scripts. You're juggling connection strings across environments, manually wiring service dependencies, and struggling to trace issues across your microservices. Development setup becomes a ritual of precision—start the database, then the cache, then service A before service B—and any misstep sends you back to square one.
+
+Aspire cuts through this complexity with a unified orchestration layer that treats your entire application as a cohesive system. Define your services and their relationships once in code ([the AppHost](/get-started/app-host/)), and Aspire handles service discovery, injects configuration automatically, and provides a dashboard with logs, traces, and metrics out of the box. Whether you're orchestrating C#, Python, or JavaScript services—or all three together—you get the same consistent experience from development through deployment.
+
+The best part? You can adopt Aspire incrementally. Start with orchestration, add observability when you're ready, integrate external services as needed. Your existing codebase stays largely unchanged, and you can reverse course if Aspire isn't the right fit.
+
+## Prerequisites
+
+Before you begin, ensure you have the following prerequisites installed based on your application's language:
+
+### Common requirements
+
+- [.NET SDK 10.0 or later](/get-started/prerequisites/) — Required for the Aspire AppHost, regardless of your application's language.
+- [Aspire CLI installed](/get-started/install-cli/) — For orchestration and deployment commands.
+- An existing application to add Aspire to.
+
+### Language-specific requirements
+
+
+
+**For C# applications:**
+
+- A solution with one or more .NET or ASP.NET Core projects (`.csproj`)
+- Visual Studio 2022 17.13 or later, Visual Studio Code, or JetBrains Rider (optional)
+
+**Example project types:**
+- ASP.NET Core Minimal API
+- ASP.NET Core Razor Pages or Blazor applications
+- Console applications
+- Worker services
+- gRPC services
+- Azure Functions
+
+
+
+
+**For Python applications:**
+
+- [Python 3.10 or later](https://www.python.org/downloads/) installed
+- [uv](https://docs.astral.sh/uv/) (recommended) or pip for package management
+- An existing Python application
+
+**Example application types:**
+- FastAPI web applications
+- Flask web applications
+- Django applications
+- Python scripts or worker processes
+- Streamlit or other Python web frameworks
+
+
+
+
+**For JavaScript/TypeScript applications:**
+
+- [Node.js 22 or later](https://nodejs.org/) installed
+- npm, yarn, or pnpm for package management
+- An existing JavaScript/TypeScript application
+
+**Example application types:**
+- React, Vue, or Svelte applications (especially Vite-based)
+- Node.js/Express APIs
+- Next.js applications
+- Angular applications
+- TypeScript backend services
+
+
+
+
+
+## Overview of the process
+
+Adding Aspire to an existing application follows these key steps:
+
+
+
+1. **Initialize Aspire support** — Use `aspire init` to add the AppHost (orchestration layer)
+2. **Add your applications** — Register C#, Python, and JavaScript applications in the AppHost
+3. **Configure telemetry (optional)** — Add OpenTelemetry instrumentation for observability
+4. **Add integrations (optional)** — Connect to databases, caches, and message queues
+5. **Run and verify** — Test your application with Aspire orchestration
+
+
+
+## Initialize Aspire support
+
+The `aspire init` command is the starting point for adding Aspire to your existing application. This command analyzes your project structure and adds an AppHost that orchestrates your services.
+
+
+
+1. Navigate to your project directory:
+
+
+ ```bash title="Navigate to your solution directory"
+ cd /path/to/your-solution
+ ```
+
+
+ ```bash title="Navigate to your project root"
+ cd /path/to/your-project
+ ```
+
+
+ ```bash title="Navigate to your workspace root"
+ cd /path/to/your-workspace
+ ```
+
+
+2. Run `aspire init` to initialize Aspire support:
+
+ ```bash title="Initialize Aspire"
+ aspire init
+ ```
+
+ The `aspire init` command runs in **interactive mode** by default. It will:
+
+
+ - Detect your existing solution structure
+ - Create a project-based AppHost (an _AppHost_ project with `AppHost.cs`)
+ - Analyze your projects and suggest which ones to add to the orchestration
+ - Install necessary Aspire packages
+
+
+ - Detect your existing project structure
+ - Create a file-based AppHost (`apphost.cs`)
+ - Analyze your Python applications and suggest which ones to add to the orchestration
+ - Install necessary Aspire packages
+
+
+ - Detect your existing workspace structure
+ - Create a file-based AppHost (`apphost.cs`)
+ - Analyze your JavaScript/Node.js applications and suggest which ones to add to the orchestration
+ - Install necessary Aspire packages
+
+
+
+ For more details on the `aspire init` command and its options, see the [CLI reference: `aspire init`](/reference/cli/commands/aspire-init/).
+
+
+
+
+### What does `aspire init` create?
+
+
+After running `aspire init`, your solution will have a project-based AppHost:
+
+
+- ExampleEcommerce.sln (updated)
+- src/
+ - **ExampleEcommerce.AppHost/** (new) orchestration project
+ - **ExampleEcommerce.AppHost.csproj** project file
+ - **AppHost.cs** orchestration code
+ - Api/
+ - ExampleEcommerce.Api.csproj
+ - Program.cs
+ - Controllers/
+ - Web/
+ - ExampleEcommerce.Web.csproj
+ - Program.cs
+ - Pages/
+ - OrderProcessor/
+ - ExampleEcommerce.OrderProcessor.csproj
+ - Worker.cs
+
+
+A typical e-commerce solution with a web frontend, API service, and background worker.
+
+
+After running `aspire init`, your project will have a file-based AppHost:
+
+
+- my-saas-app/
+ - **apphost.cs** (new) orchestration code
+ - **apphost.run.json** (new) configuration
+ - api/
+ - main.py
+ - routers/
+ - models/
+ - pyproject.toml
+ - frontend/
+ - app.py
+ - templates/
+ - static/
+ - requirements.txt
+ - worker/
+ - tasks.py
+ - celery_config.py
+ - requirements.txt
+
+
+A typical SaaS application with FastAPI backend, Flask frontend, and Celery worker.
+
+
+After running `aspire init`, your project will have a file-based AppHost:
+
+
+- my-store/
+ - **apphost.cs** (new) orchestration code
+ - **apphost.run.json** (new) configuration
+ - packages/
+ - api/
+ - src/
+ - server.js
+ - routes/
+ - package.json
+ - web/
+ - src/
+ - App.tsx
+ - components/
+ - package.json
+ - vite.config.ts
+ - admin/
+ - src/
+ - main.ts
+ - views/
+ - package.json
+ - package.json (workspace root)
+
+
+A typical monorepo with Node.js API, React storefront, and admin dashboard.
+
+
+
+The `AppHost.cs` file in your new AppHost project initially contains a minimal starter:
+
+```csharp title="AppHost.cs — Initial state after aspire init"
+var builder = DistributedApplication.CreateBuilder(args);
+
+// TODO: Add resources here
+
+builder.Build().Run();
+```
+
+
+
+The `apphost.cs` file initially contains a minimal starter:
+
+```csharp title="apphost.cs — Initial state after aspire init"
+#:sdk Aspire.AppHost.Sdk@13.1.0
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+// TODO: Add resources here
+
+builder.Build().Run();
+```
+
+
+
+The `apphost.cs` file initially contains a minimal starter:
+
+```csharp title="apphost.cs — Initial state after aspire init"
+#:sdk Aspire.AppHost.Sdk@13.1.0
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+// TODO: Add resources here
+
+builder.Build().Run();
+```
+
+
+
+This is your starting point. In the next section, you'll add your applications and configure their relationships.
+
+## Add your applications to the AppHost
+
+Once you have an AppHost, you need to register your existing applications. First, install the appropriate hosting packages for your application types, then add your resources to the AppHost.
+
+### Install hosting packages
+
+
+
+For C# projects, if you're using project-based orchestration (`.csproj` files), no additional packages are needed. The base Aspire SDK includes support for `AddProject` (or `AddCSharpApp` for file-based apps).
+
+
+
+
+For Python applications, install the Python hosting package:
+
+
+
+This package provides methods like `AddUvicornApp`, `AddPythonApp`, and `AddPythonModule`.
+
+
+
+
+For JavaScript/TypeScript applications, install the JavaScript hosting package:
+
+
+
+This package provides methods like `AddViteApp`, `AddNodeApp`, and `AddJavaScriptApp`.
+
+
+
+### Add C# project references
+
+
+
+Before you can use `AddProject` in your AppHost, the AppHost project must have a project reference to each C# project it orchestrates. These project references are what generate the `Projects.YourProject` marker types used by `AddProject`.
+
+If you used `aspire init`, it likely added these references automatically for the projects you selected. If you need to add more projects later, run the following commands from your AppHost project directory:
+
+```bash title=".NET CLI — Add project references to AppHost"
+dotnet add reference ../Api/ExampleCommerce.Api.csproj
+dotnet add reference ../Web/ExampleCommerce.Web.csproj
+dotnet add reference ../OrderProcessor/ExampleCommerce.OrderProcessor.csproj
+```
+
+This updates the AppHost `.csproj` file with entries like:
+
+```xml title="ExampleCommerce.AppHost.csproj — Project references"
+
+
+
+
+
+```
+
+
+
+
+This step only applies to C# project-based AppHosts. Python and JavaScript application resources don't use `.csproj` project references.
+
+
+
+### Model your resources in the AppHost
+
+
+Now update your `AppHost.cs` file in the AppHost project to register your applications as resources. Resources are the building blocks of your distributed application—each service, container, or infrastructure resource becomes something Aspire can orchestrate.
+
+
+Now update your `apphost.cs` file to register your applications as resources. Resources are the building blocks of your distributed application—each service, container, or infrastructure resource becomes something Aspire can orchestrate.
+
+
+
+
+For C# projects, use `AddProject` to reference your existing C# projects:
+
+```csharp title="AppHost.cs — Complete e-commerce example"
+var builder = DistributedApplication.CreateBuilder(args);
+
+var api = builder.AddProject("api")
+ .WithHttpHealthCheck("/health");
+
+var web = builder.AddProject("web")
+ .WithExternalHttpEndpoints()
+ .WithReference(api)
+ .WaitFor(api);
+
+var orderProcessor = builder.AddProject("orderprocessor")
+ .WithReference(api);
+
+builder.Build().Run();
+```
+
+**Key methods:**
+- `AddProject` - Adds a .NET project from your solution
+- `WithHttpHealthCheck` - Monitors service health via HTTP endpoint
+- `WithReference` - Enables service-to-service communication
+- `WaitFor` - Ensures proper startup order
+
+
+
+
+Aspire provides several methods for Python applications:
+
+```csharp title="apphost.cs — Complete SaaS example"
+#:sdk Aspire.AppHost.Sdk@13.1.0
+#:package Aspire.Hosting.Python@13.1.0
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+// FastAPI backend
+var api = builder.AddUvicornApp("api", "./api", "main:app")
+ .WithUv()
+ .WithHttpHealthCheck("/health");
+
+// Flask frontend
+var frontend = builder.AddUvicornApp("frontend", "./frontend", "app:app")
+ .WithUv()
+ .WithExternalHttpEndpoints()
+ .WithReference(api)
+ .WaitFor(api);
+
+// Celery worker
+var worker = builder.AddPythonApp("worker", "./worker", "celery")
+ .WithUv()
+ .WithArgs("worker", "-A", "tasks")
+ .WithReference(api);
+
+builder.Build().Run();
+```
+
+**Key methods:**
+- `AddUvicornApp` - For FastAPI, Flask, and other ASGI/WSGI frameworks
+- `AddPythonApp` - For standalone Python scripts
+- `WithUv()` - Use uv for fast package management (recommended)
+- `WithPip()` - Use traditional pip for package management
+
+
+
+
+For JavaScript applications, use the appropriate method based on your application type:
+
+```csharp title="apphost.cs — Complete monorepo example"
+#:sdk Aspire.AppHost.Sdk@13.1.0
+#:package Aspire.Hosting.JavaScript@13.1.0
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+// Node.js API
+var api = builder.AddNodeApp("api", "./packages/api", "src/server.js")
+ .WithNpm()
+ .WithHttpHealthCheck("/health");
+
+// React storefront
+var web = builder.AddViteApp("web", "./packages/web")
+ .WithExternalHttpEndpoints()
+ .WithReference(api)
+ .WaitFor(api);
+
+// Admin dashboard
+var admin = builder.AddViteApp("admin", "./packages/admin")
+ .WithExternalHttpEndpoints()
+ .WithReference(api)
+ .WaitFor(api);
+
+builder.Build().Run();
+```
+
+**Key methods:**
+- `AddViteApp` - For Vite-based applications (React, Vue, Svelte)
+- `AddNodeApp` - For Node.js applications
+- `AddJavaScriptApp` - For generic JavaScript applications with npm/yarn/pnpm
+ - `WithNpm()` / `WithYarn()` / `WithPnpm()` - Specify package manager
+- `WithRunScript` - Specify which npm script to run during development
+
+:::note[Passing arguments to scripts]
+Unlike the deprecated `AddNpmApp` API in Aspire 9, the new JavaScript hosting methods (`AddJavaScriptApp`, `AddViteApp`, `AddNodeApp`) do not support an `args` constructor parameter. You have two options to pass arguments to your scripts:
+
+**Option 1: Use `WithArgs` to pass arguments directly**
+
+```csharp title="apphost.cs — Pass arguments using WithArgs"
+builder.AddViteApp("frontend", "./frontend")
+ .WithArgs("--no-open");
+```
+
+**Option 2: Define custom scripts in `package.json` with arguments**
+
+```json title="package.json"
+{
+ "scripts": {
+ "dev": "vite",
+ "dev:no-open": "vite --no-open"
+ }
+}
+```
+
+```csharp title="apphost.cs — Reference custom script"
+builder.AddViteApp("frontend", "./frontend")
+ .WithRunScript("dev:no-open");
+```
+
+Option 2 keeps all script configuration in `package.json`, making your scripts more discoverable and easier to run outside of Aspire (e.g., `npm run dev:no-open`).
+:::
+
+
+
+
+
+### Connect services
+
+The `WithReference` calls establish service dependencies and enable service discovery:
+
+
+
+```csharp title="AppHost.cs — Connect C# services" ".WithReference"
+// Omitted for brevity...
+
+var api = builder.AddProject("api");
+
+var web = builder.AddProject("web")
+ .WithReference(api); // Web can call API
+
+var worker = builder.AddProject("worker")
+ .WithReference(api); // Worker can call API
+
+// Omitted for brevity...
+```
+
+
+
+
+```csharp title="apphost.cs — Connect Python services" ".WithReference"
+// Omitted for brevity...
+
+var api = builder.AddUvicornApp("api", "../python-api", "main:app")
+ .WithUv();
+
+var worker = builder.AddPythonApp("worker", "../python-worker", "worker.py")
+ .WithReference(api); // Worker gets API_HTTP and API_HTTPS env vars
+
+// Omitted for brevity...
+```
+
+
+
+
+```csharp title="apphost.cs — Connect JavaScript services" ".WithReference"
+// Omitted for brevity...
+
+var api = builder.AddNodeApp("api", "../node-api", "server.js")
+ .WithNpm();
+
+var frontend = builder.AddViteApp("frontend", "../react-frontend")
+ .WithReference(api); // Frontend gets API_HTTP and API_HTTPS env vars
+
+// Omitted for brevity...
+```
+
+
+
+When you call `WithReference`, you're declaring a dependency between resources. Aspire handles the rest—automatically injecting configuration at runtime and during deployment so your services can communicate seamlessly, whether running locally or in production.
+
+## Add telemetry configuration (optional)
+
+
+
+ServiceDefaults provide a standardized way to add observability, resilience, and health checks to .NET services. This step is optional but recommended for production applications.
+
+
+
+1. During the `aspire init` process, you may be prompted to add ServiceDefaults. If you chose not to add it initially, you can add it later using the Aspire CLI or manually.
+
+2. To add ServiceDefaults to a project manually:
+
+ ```bash title=".NET CLI — Add ServiceDefaults to your project"
+ dotnet new aspire-servicedefaults -n YourProject.ServiceDefaults
+ dotnet sln add YourProject.ServiceDefaults
+ dotnet add YourProject reference YourProject.ServiceDefaults
+ ```
+
+3. Update your project's `Program.cs` to use ServiceDefaults:
+
+ ```csharp title="Program.cs — Add ServiceDefaults"
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add Aspire ServiceDefaults for observability and resilience
+ builder.AddServiceDefaults();
+
+ // ... your existing service configuration ...
+
+ var app = builder.Build();
+
+ // Map Aspire ServiceDefaults endpoints
+ app.MapDefaultEndpoints();
+
+ // ... your existing middleware ...
+
+ app.Run();
+ ```
+
+
+
+
+ For more information on ServiceDefaults, see [Service Defaults](/fundamentals/service-defaults/).
+
+
+
+
+
+Python applications can send telemetry to the Aspire dashboard using OpenTelemetry:
+
+
+
+1. Install OpenTelemetry packages in your Python application:
+
+ ```bash title="Install OpenTelemetry packages"
+ uv add opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc
+ uv add opentelemetry-instrumentation-fastapi # For FastAPI
+ # Or for Flask:
+ # uv add opentelemetry-instrumentation-flask
+ ```
+
+2. Configure OpenTelemetry in your Python application:
+
+ ```python title="Python — Configure OpenTelemetry"
+ import os
+ from opentelemetry import trace, metrics
+ from opentelemetry.sdk.trace import TracerProvider
+ from opentelemetry.sdk.metrics import MeterProvider
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
+ from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
+ from opentelemetry.sdk.resources import Resource
+ from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
+
+ # Get OTLP endpoint from environment (injected by Aspire)
+ otlp_endpoint = os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
+
+ # Configure tracing and metrics
+ resource = Resource.create({"service.name": "api"})
+ trace.set_tracer_provider(TracerProvider(resource=resource))
+ metrics.set_meter_provider(MeterProvider(resource=resource))
+
+ # Instrument your FastAPI app
+ FastAPIInstrumentor.instrument_app(app)
+ ```
+
+
+
+
+
+
+JavaScript/Node.js applications can also send telemetry using OpenTelemetry:
+
+
+
+1. Install OpenTelemetry packages:
+
+ ```bash title="Install OpenTelemetry packages"
+ npm install @opentelemetry/api @opentelemetry/sdk-node \
+ @opentelemetry/auto-instrumentations-node \
+ @opentelemetry/exporter-trace-otlp-grpc \
+ @opentelemetry/exporter-metrics-otlp-grpc
+ ```
+
+2. Create a telemetry configuration file:
+
+ ```javascript title="JavaScript — telemetry.js"
+ const { NodeSDK } = require('@opentelemetry/sdk-node');
+ const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
+ const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
+ const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc');
+ const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
+ const { resourceFromAttributes } = require('@opentelemetry/resources');
+ const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
+
+ const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4317';
+
+ // Create resource with service name
+ const resource = resourceFromAttributes({
+ [ATTR_SERVICE_NAME]: 'frontend',
+ });
+
+ const sdk = new NodeSDK({
+ resource: resource,
+ traceExporter: new OTLPTraceExporter({ url: otlpEndpoint }),
+ metricReader: new PeriodicExportingMetricReader({
+ exporter: new OTLPMetricExporter({ url: otlpEndpoint })
+ }),
+ instrumentations: [getNodeAutoInstrumentations()]
+ });
+
+ sdk.start();
+ ```
+
+3. Import the telemetry configuration at the top of your application entry point:
+
+ ```javascript title="JavaScript — app.js"
+ // This must be first!
+ require('./telemetry');
+
+ const express = require('express');
+ // ... rest of your app
+ ```
+
+
+
+
+
+## Add integrations (optional)
+
+Aspire provides integration libraries that simplify working with common services like Redis, PostgreSQL, RabbitMQ, and more. These integrations handle configuration, health checks, and telemetry automatically.
+
+When you add a hosting integration (like Redis) to your AppHost and reference it from a dependent resource, Aspire automatically injects the necessary configuration. This includes connection strings, URLs, environment variables, and other service-specific settings—eliminating manual connection string management across your services.
+
+
+
+1. Identify which services in your application could benefit from Aspire integrations. Common candidates include:
+
+ - Databases (PostgreSQL, SQL Server, MongoDB)
+ - Caching (Redis, Valkey)
+ - Messaging (RabbitMQ, Azure Service Bus, Kafka)
+ - Storage (Azure Blob Storage, AWS S3)
+
+2. Use the `aspire add` command to add integration packages to your AppHost:
+
+ ```bash title="Add a Redis integration"
+ aspire add redis
+ ```
+
+ This command adds the necessary NuGet packages and helps you configure the integration.
+
+3. Update your AppHost to reference the integration and share it across all your services:
+
+ ```csharp title="apphost.cs — Add Redis integration for multi-language apps"
+ var builder = DistributedApplication.CreateBuilder(args);
+
+ // Add Redis resource
+ var cache = builder.AddRedis("cache");
+
+ // Share Redis with .NET API
+ var api = builder.AddProject("api")
+ .WithReference(cache)
+ .WithHttpHealthCheck("/health");
+
+ // Share Redis with Python worker
+ var pythonWorker = builder.AddPythonApp("worker", "../python-worker", "worker.py")
+ .WithReference(cache); // Python gets CACHE_HOST, CACHE_PORT env vars
+
+ // Share Redis with Node.js service
+ var nodeService = builder.AddNodeApp("service", "../node-service", "index.js")
+ .WithReference(cache); // Node.js gets CACHE_HOST, CACHE_PORT env vars
+
+ builder.Build().Run();
+ ```
+
+4. Configure the integration in each language:
+
+
+
+ ```bash title="Add Redis client to .NET project"
+ dotnet add YourApi package Aspire.StackExchange.Redis
+ ```
+
+ ```csharp title="Program.cs — Configure Redis client"
+ var builder = WebApplication.CreateBuilder(args);
+ builder.AddRedisClient("cache");
+ ```
+
+
+
+
+ ```bash title="Add Redis client to Python project"
+ uv add redis
+ ```
+
+ ```python title="Python — Configure Redis client"
+ import os
+ import redis
+
+ # Aspire injects CACHE_HOST and CACHE_PORT
+ redis_client = redis.Redis(
+ host=os.getenv("CACHE_HOST"),
+ port=int(os.getenv("CACHE_PORT")),
+ decode_responses=True
+ )
+ ```
+
+
+
+
+ ```bash title="Add Redis client to Node.js project"
+ npm install redis
+ ```
+
+ ```javascript title="JavaScript — Configure Redis client"
+ const redis = require('redis');
+
+ // Aspire injects CACHE_HOST and CACHE_PORT
+ const client = redis.createClient({
+ socket: {
+ host: process.env.CACHE_HOST,
+ port: process.env.CACHE_PORT
+ }
+ });
+ ```
+
+
+
+
+
+
+ Browse available integrations in the [Integrations section](/integrations/gallery/).
+
+
+## Run and verify
+
+Now that you've added Aspire to your application, it's time to run it and see the orchestration in action.
+
+
+
+1. From your solution directory, run the application using the Aspire CLI:
+
+ ```bash title="Run your application with Aspire"
+ aspire run
+ ```
+
+ The Aspire CLI will:
+ - Find your AppHost (file-based `apphost.cs`)
+ - Build your solution
+ - Launch all orchestrated services
+ - Start the Aspire dashboard
+
+2. The dashboard URL will appear in your terminal output:
+
+ ```bash title="Example output" mark={4}
+ 🔍 Finding apphosts...
+ apphost.cs
+
+ Dashboard: https://localhost:17068/login?t=ea559845d54cea66b837dc0ff33c3bd3
+
+ Logs: ~/.aspire/cli/logs/apphost-13024-2025-11-19-12-00-00.log
+
+ Press CTRL+C to stop the apphost and exit.
+ ```
+
+3. Open the dashboard in your browser using the provided URL. You'll see:
+
+ - All your orchestrated resources and their status
+ - Real-time logs from each service
+ - Traces and metrics for observability
+ - Environment variables and configuration
+
+4. Verify that your services are running correctly by:
+
+ - Checking the **Resources** page for service health
+ - Accessing your application endpoints
+ - Reviewing logs and traces in the dashboard
+
+5. Stop the application by pressing in your terminal.
+
+
+
+
+
+### Bonus content
+
+If you're currently using Docker Compose to orchestrate your services, Aspire can replace it while providing additional benefits:
+
+
+
+```yaml title="docker-compose.yml" showLineNumbers
+services:
+ postgres:
+ image: postgres:latest
+ environment:
+ - POSTGRES_PASSWORD=postgres
+ - POSTGRES_DB=mydb
+ ports:
+ - "5432:5432"
+
+ api:
+ build: ./api
+ ports:
+ - "8080:8080"
+ environment:
+ - DATABASE_URL=postgres://postgres:postgres@postgres:5432/mydb
+ depends_on:
+ - postgres
+
+ web:
+ build: ./web
+ ports:
+ - "3000:3000"
+ environment:
+ - API_URL=http://api:8080
+ depends_on:
+ - api
+```
+
+
+```csharp title="apphost.cs" showLineNumbers
+var builder = DistributedApplication.CreateBuilder(args);
+
+var db = builder.AddPostgres("postgres")
+ .AddDatabase("mydb");
+
+var api = builder.AddProject("api")
+ .WithReference(db);
+
+var web = builder.AddProject("web")
+ .WithExternalHttpEndpoints()
+ .WithReference(api)
+ .WaitFor(api);
+
+builder.Build().Run();
+```
+
+
+
+**Key advantages of Aspire over Docker Compose:**
+
+- **Literally, less verbose** — Yet, more expressive and powerful.
+- **No manual URL configuration** — Services discover each other automatically.
+- **Type-safe references** — Compile-time checking for service dependencies.
+- **Built-in dashboard** — Observability without additional tools like Prometheus/Grafana.
+- **Development and deployment** — Same orchestration code works locally and can generate Docker Compose or deploy anywhere.
+- **Integration libraries** — Pre-built support for databases, caches, message queues with best practices.
+- **Language-agnostic** — Works with C#, Python, JavaScript, many more, and containerized services.
+
+
+
+## Next steps
+
+Congratulations! You've successfully added Aspire to your existing application. Here are some recommended next steps:
+
+- **Add more integrations** — Explore [Aspire integrations](/integrations/gallery/) to simplify working with databases, caches, and message queues
+- **Configure observability** — Enhance your application's telemetry:
+
+ - Learn about [Service Defaults](/fundamentals/service-defaults/)
+
+
+ - See [Standalone dashboard for Python](/dashboard/standalone-for-python/)
+
+
+ - See [Standalone dashboard for Node.js](/dashboard/standalone-for-nodejs/)
+
+- **Deploy your app** — Follow the [Deploy your first app](/get-started/deploy-first-app/) tutorial to deploy your Aspire application
+- **Use the VS Code extension** — Run, debug, and manage integrations from within VS Code with the [Aspire extension](/get-started/aspire-vscode-extension/)
+- **Explore the dashboard** — Learn more about the [Aspire dashboard](/dashboard/overview/) and its features
+- **Learn about multi-language features**:
+ - [Python support in Aspire](/whats-new/aspire-13/#python-as-a-first-class-citizen)
+ - [JavaScript support in Aspire](/whats-new/aspire-13/#javascript-as-a-first-class-citizen)
diff --git a/src/frontend/src/content/docs/get-started/add-aspire-existing-app-typescript-apphost.mdx b/src/frontend/src/content/docs/get-started/add-aspire-existing-app-typescript-apphost.mdx
new file mode 100644
index 000000000..4842133ed
--- /dev/null
+++ b/src/frontend/src/content/docs/get-started/add-aspire-existing-app-typescript-apphost.mdx
@@ -0,0 +1,584 @@
+---
+title: "Aspireify an existing app with a TypeScript AppHost"
+description: "Learn how to add Aspire orchestration to an existing JavaScript or TypeScript application by using a TypeScript AppHost."
+prev: false
+next: false
+---
+
+import { Aside, Steps, FileTree, Tabs, TabItem } from '@astrojs/starlight/components';
+import { Kbd } from 'starlight-kbd/components'
+import LearnMore from '@components/LearnMore.astro';
+
+
+This guide shows you how to add Aspire orchestration to an existing JavaScript or TypeScript application while using a TypeScript AppHost (`apphost.ts`). You'll initialize Aspire with `aspire init --language typescript`, model your resources in `apphost.ts`, and run the app locally with Aspire.
+
+:::note[Definition]{icon="approve-check-circle"}
+**Aspireify** (verb): To transform an existing application into a distributed, observable, and orchestrated system by adding Aspire—no cape required, just a few commands!
+:::
+
+## Why add Aspire to an existing app?
+
+As distributed applications grow, coordinating multiple services becomes a tangled web of configuration files, hard-coded URLs, and fragile startup scripts. You're juggling connection strings across environments, manually wiring service dependencies, and struggling to trace issues across your microservices. Development setup becomes a ritual of precision—start the database, then the cache, then service A before service B—and any misstep sends you back to square one.
+
+Aspire cuts through this complexity with a unified orchestration layer that treats your entire application as a cohesive system. Define your services and their relationships once in code ([the AppHost](/get-started/app-host/)), and Aspire handles service discovery, injects configuration automatically, and provides a dashboard with logs, traces, and metrics out of the box. When you're orchestrating JavaScript and TypeScript services, you get the same consistent experience from development through deployment.
+
+The best part? You can adopt Aspire incrementally. Start with orchestration, add observability when you're ready, integrate external services as needed. Your existing codebase stays largely unchanged, and you can reverse course if Aspire isn't the right fit.
+
+## Prerequisites
+
+Before you begin, ensure you have the following prerequisites installed:
+
+### Common requirements
+
+- [Aspire CLI installed](/get-started/install-cli/) — For orchestration and deployment commands.
+- An existing application to add Aspire to.
+
+### Language-specific requirements
+
+
+
+**For JavaScript/TypeScript applications:**
+
+- [Node.js 22 or later](https://nodejs.org/) installed
+- npm, yarn, or pnpm for package management
+- An existing JavaScript/TypeScript application
+
+**Example application types:**
+- React, Vue, or Svelte applications (especially Vite-based)
+- Node.js/Express APIs
+- Next.js applications
+- Angular applications
+- TypeScript backend services
+
+
+
+
+## Overview of the process
+
+Adding Aspire to an existing application follows these key steps:
+
+
+
+1. **Initialize Aspire support** — Use `aspire init` to add the AppHost (orchestration layer)
+2. **Add your applications** — Register your JavaScript and TypeScript applications in the AppHost
+3. **Configure telemetry (optional)** — Add OpenTelemetry instrumentation for observability
+4. **Add integrations (optional)** — Connect to databases, caches, and message queues
+5. **Run and verify** — Test your application with Aspire orchestration
+
+
+
+## Initialize Aspire support
+
+The `aspire init` command is the starting point for adding Aspire to your existing application. It adds an AppHost that orchestrates your services while letting those services stay in their current languages.
+
+
+
+1. Navigate to your project directory:
+
+
+
+ ```bash title="Navigate to your workspace root"
+ cd /path/to/your-workspace
+ ```
+
+
+
+2. Run `aspire init` to initialize Aspire support:
+
+
+ ```bash title="Initialize Aspire with a TypeScript AppHost"
+ aspire init --language typescript
+ ```
+
+
+
+
+
+ The `aspire init` command still runs in **interactive mode** for the remaining setup. It will:
+
+
+
+ - Detect your existing workspace structure
+ - Create a TypeScript AppHost (`apphost.ts`)
+ - Add the generated AppHost SDK and config files
+ - Install the supporting Node.js dependencies for the AppHost
+
+
+
+
+ For more details on the `aspire init` command and its options, see the [CLI reference: `aspire init`](/reference/cli/commands/aspire-init/).
+
+
+
+
+### What does `aspire init` create?
+
+
+
+After running `aspire init --language typescript`, your project will have a TypeScript AppHost:
+
+
+- my-store/
+ - **apphost.ts** (new) orchestration code
+ - **.modules/** (new) generated SDK
+ - **aspire.config.json** (new) configuration
+ - **package.json** (new) AppHost dependencies
+ - **tsconfig.json** (new) TypeScript configuration
+ - packages/
+ - api/
+ - src/
+ - server.js
+ - routes/
+ - package.json
+ - web/
+ - src/
+ - App.tsx
+ - components/
+ - package.json
+ - vite.config.ts
+ - admin/
+ - src/
+ - main.ts
+ - views/
+ - package.json
+ - package.json (workspace root)
+
+
+A typical monorepo with Node.js API, React storefront, and admin dashboard.
+
+
+
+
+
+
+The `apphost.ts` file initially contains a minimal starter:
+
+```typescript title="apphost.ts — Initial state after aspire init"
+// Aspire TypeScript AppHost
+// For more information, see: https://aspire.dev
+
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+// Add your resources here, for example:
+// const redis = await builder.addContainer("cache", "redis:latest");
+// const postgres = await builder.addPostgres("db");
+
+await builder.build().run();
+```
+
+
+This is your starting point. In the next section, you'll add your applications and configure their relationships.
+
+## Add your applications to the AppHost
+
+Once you have an AppHost, you need to register your existing applications. First, install the appropriate hosting packages for your application types, then add your resources to the AppHost.
+
+### Install hosting packages
+
+
+
+For JavaScript/TypeScript applications, add the JavaScript hosting integration to your AppHost:
+
+```bash title="Aspire CLI — Add JavaScript hosting integration"
+aspire add javascript
+```
+
+This updates the generated AppHost SDK with methods like `addViteApp`, `addNodeApp`, and `addJavaScriptApp`.
+
+
+### Model your resources in the AppHost
+
+
+
+Now update your `apphost.ts` file to register your applications as resources. Resources are the building blocks of your distributed application—each service, container, or infrastructure resource becomes something Aspire can orchestrate.
+
+
+
+
+For JavaScript applications, use the appropriate method based on your application type:
+
+```typescript title="apphost.ts — Complete monorepo example"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+// Node.js API
+const api = await builder
+ .addNodeApp("api", "./packages/api", "src/server.js")
+ .withNpm()
+ .withHttpHealthCheck({ path: "/health" });
+
+// React storefront
+const web = await builder
+ .addViteApp("web", "./packages/web")
+ .withExternalHttpEndpoints()
+ .withReference(api)
+ .waitFor(api);
+
+// Admin dashboard
+const admin = await builder
+ .addViteApp("admin", "./packages/admin")
+ .withExternalHttpEndpoints()
+ .withReference(api)
+ .waitFor(api);
+
+await builder.build().run();
+```
+
+**Key methods:**
+- `addViteApp` - For Vite-based applications (React, Vue, Svelte)
+- `addNodeApp` - For Node.js applications
+- `addJavaScriptApp` - For generic JavaScript applications with npm/yarn/pnpm
+ - `withNpm()` / `withYarn()` / `withPnpm()` - Specify package manager
+- `withRunScript` - Specify which npm script to run during development
+
+:::note[Passing arguments to scripts]
+Unlike the deprecated `AddNpmApp` API in Aspire 9, the new JavaScript hosting methods (`addJavaScriptApp`, `addViteApp`, `addNodeApp`) do not support an `args` constructor parameter. You have two options to pass arguments to your scripts:
+
+**Option 1: Use `withArgs` to pass arguments directly**
+
+```typescript title="apphost.ts — Pass arguments using withArgs"
+await builder
+ .addViteApp("frontend", "./frontend")
+ .withArgs(["--no-open"]);
+```
+
+**Option 2: Define custom scripts in `package.json` with arguments**
+
+```json title="package.json"
+{
+ "scripts": {
+ "dev": "vite",
+ "dev:no-open": "vite --no-open"
+ }
+}
+```
+
+```typescript title="apphost.ts — Reference custom script"
+await builder
+ .addViteApp("frontend", "./frontend")
+ .withRunScript("dev:no-open");
+```
+
+Option 2 keeps all script configuration in `package.json`, making your scripts more discoverable and easier to run outside of Aspire (e.g., `npm run dev:no-open`).
+:::
+
+
+
+
+### Connect services
+
+The `withReference` calls establish service dependencies and enable service discovery:
+
+
+
+```typescript title="apphost.ts — Connect JavaScript services" ".withReference"
+// Omitted for brevity...
+
+const api = await builder
+ .addNodeApp("api", "../node-api", "server.js")
+ .withNpm();
+
+await builder
+ .addViteApp("frontend", "../react-frontend")
+ .withReference(api); // Frontend gets API_HTTP and API_HTTPS env vars
+
+// Omitted for brevity...
+```
+
+
+When you call `withReference`, you're declaring a dependency between resources. Aspire handles the rest—automatically injecting configuration at runtime and during deployment so your services can communicate seamlessly, whether running locally or in production.
+
+## Add telemetry configuration (optional)
+
+
+
+TypeScript Node.js applications can also send telemetry using OpenTelemetry. The example below uses TypeScript and ESM imports so it fits naturally into a TypeScript codebase. If your app uses plain JavaScript, keep the same structure but use `.js` files and your existing module syntax.
+
+
+
+1. Install OpenTelemetry packages:
+
+ ```bash title="Install OpenTelemetry packages"
+ npm install @opentelemetry/api @opentelemetry/sdk-node \
+ @opentelemetry/auto-instrumentations-node \
+ @opentelemetry/exporter-trace-otlp-grpc \
+ @opentelemetry/exporter-metrics-otlp-grpc
+ ```
+
+2. Create a telemetry configuration file:
+
+ ```typescript title="TypeScript — telemetry.ts"
+ import { NodeSDK } from '@opentelemetry/sdk-node';
+ import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
+ import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
+ import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
+ import { resourceFromAttributes } from '@opentelemetry/resources';
+ import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
+
+ const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? 'http://localhost:4317';
+
+ const resource = resourceFromAttributes({
+ [ATTR_SERVICE_NAME]: 'api',
+ });
+
+ const sdk = new NodeSDK({
+ resource,
+ traceExporter: new OTLPTraceExporter({ url: otlpEndpoint }),
+ metricReader: new PeriodicExportingMetricReader({
+ exporter: new OTLPMetricExporter({ url: otlpEndpoint }),
+ }),
+ instrumentations: [getNodeAutoInstrumentations()],
+ });
+
+ sdk.start();
+ ```
+
+3. Import the telemetry configuration at the top of your application entry point:
+
+ ```typescript title="TypeScript — src/server.ts"
+ // This must be first!
+ import './telemetry';
+
+ import express from 'express';
+
+ const app = express();
+ // ... rest of your app
+ ```
+
+
+
+
+## Add integrations (optional)
+
+Aspire provides integration libraries that simplify working with common services like Redis, PostgreSQL, RabbitMQ, and more. These integrations handle configuration, health checks, and telemetry automatically.
+
+When you add a hosting integration (like Redis) to your AppHost and reference it from a dependent resource, Aspire automatically injects the necessary configuration. This includes connection strings, URLs, environment variables, and other service-specific settings—eliminating manual connection string management across your services.
+
+
+
+1. Identify which services in your application could benefit from Aspire integrations. Common candidates include:
+
+ - Databases (PostgreSQL, SQL Server, MongoDB)
+ - Caching (Redis, Valkey)
+ - Messaging (RabbitMQ, Azure Service Bus, Kafka)
+ - Storage (Azure Blob Storage, AWS S3)
+
+2. Use the `aspire add` command to add integration packages to your AppHost:
+
+ ```bash title="Add a Redis integration"
+ aspire add redis
+ ```
+
+ This command adds the necessary AppHost dependencies and helps you configure the integration.
+
+3. Update your AppHost to reference the integration and share it across all your services:
+
+
+ ```typescript title="apphost.ts — Add Redis integration for multiple services"
+ import { createBuilder } from './.modules/aspire.js';
+
+ const builder = await createBuilder();
+
+ const cache = await builder.addRedis("cache");
+
+ await builder
+ .addNodeApp("api", "../node-api", "server.js")
+ .withNpm()
+ .withReference(cache);
+
+ await builder
+ .addNodeApp("worker", "../node-worker", "worker.js")
+ .withNpm()
+ .withReference(cache);
+
+ await builder.build().run();
+ ```
+
+
+
+
+4. Configure the integration in each language:
+
+
+
+ ```bash title="Add Redis client to Node.js project"
+ npm install redis
+ ```
+
+ ```javascript title="JavaScript — Configure Redis client"
+ const redis = require('redis');
+
+ // Aspire injects CACHE_HOST and CACHE_PORT
+ const client = redis.createClient({
+ socket: {
+ host: process.env.CACHE_HOST,
+ port: process.env.CACHE_PORT
+ }
+ });
+ ```
+
+
+
+
+
+
+
+ Browse available integrations in the [Integrations section](/integrations/gallery/).
+
+
+## Run and verify
+
+Now that you've added Aspire to your application, it's time to run it and see the orchestration in action.
+
+
+
+1. From your app root, run the application using the Aspire CLI:
+
+ ```bash title="Run your application with Aspire"
+ aspire run
+ ```
+
+ The Aspire CLI will:
+ - Find your AppHost
+ - Build your app and its dependencies
+ - Launch all orchestrated services
+ - Start the Aspire dashboard
+
+2. The dashboard URL will appear in your terminal output:
+
+ ```bash title="Example output" mark={3}
+ 🔍 Finding apphosts...
+
+ Dashboard: https://localhost:17068/login?t=ea559845d54cea66b837dc0ff33c3bd3
+
+ Logs: ~/.aspire/cli/logs/apphost-13024-2025-11-19-12-00-00.log
+
+ Press CTRL+C to stop the apphost and exit.
+ ```
+
+ The CLI output also shows which AppHost Aspire found, such as `apphost.ts`.
+
+3. Open the dashboard in your browser using the provided URL. You'll see:
+
+ - All your orchestrated resources and their status
+ - Real-time logs from each service
+ - Traces and metrics for observability
+ - Environment variables and configuration
+
+4. Verify that your services are running correctly by:
+
+ - Checking the **Resources** page for service health
+ - Accessing your application endpoints
+ - Reviewing logs and traces in the dashboard
+
+5. Stop the application by pressing in your terminal.
+
+
+
+
+
+### Compare with Docker Compose
+
+If you're currently using Docker Compose, the example below shows how the same relationships translate into a TypeScript AppHost:
+
+
+
+```yaml title="docker-compose.yml" showLineNumbers
+services:
+ postgres:
+ image: postgres:latest
+ environment:
+ - POSTGRES_PASSWORD=postgres
+ - POSTGRES_DB=mydb
+ ports:
+ - "5432:5432"
+
+ api:
+ build: ./api
+ ports:
+ - "8080:8080"
+ environment:
+ - DATABASE_URL=postgres://postgres:postgres@postgres:5432/mydb
+ depends_on:
+ - postgres
+
+ web:
+ build: ./web
+ ports:
+ - "3000:3000"
+ environment:
+ - API_URL=http://api:8080
+ depends_on:
+ - api
+```
+
+
+
+```typescript title="apphost.ts" showLineNumbers
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const db = (await builder.addPostgres("postgres"))
+ .addDatabase("mydb");
+
+const api = await builder
+ .addNodeApp("api", "./api", "server.js")
+ .withNpm()
+ .withReference(db);
+
+await builder
+ .addViteApp("web", "./web")
+ .withExternalHttpEndpoints()
+ .withReference(api)
+ .waitFor(api);
+
+await builder.build().run();
+```
+
+
+
+
+The orchestration pattern stays the same: model the shared dependencies once, then connect services with `withReference`.
+
+**Key advantages of Aspire over Docker Compose:**
+
+- **No manual URL configuration** — Services discover each other automatically.
+- **Code-based resource references** — Define service dependencies in code instead of duplicating them in YAML.
+- **Built-in dashboard** — Observability without additional tools like Prometheus/Grafana.
+- **Reusable orchestration code** — The same AppHost definitions work locally and can also drive deployment targets.
+- **Integration libraries** — Pre-built support for databases, caches, message queues with best practices.
+
+
+
+## Next steps
+
+Congratulations! You've successfully added Aspire to your existing application. Here are some recommended next steps:
+
+- **Add more integrations** — Explore [Aspire integrations](/integrations/gallery/) to simplify working with databases, caches, and message queues
+- **Configure observability** — Enhance your application's telemetry:
+
+
+ - See [Standalone dashboard for Node.js](/dashboard/standalone-for-nodejs/)
+
+
+- **Deploy your app** — Follow the [Deploy your first app](/get-started/deploy-first-app/) tutorial to deploy your Aspire application
+- **Use the VS Code extension** — Run, debug, and manage integrations from within VS Code with the [Aspire extension](/get-started/aspire-vscode-extension/)
+- **Explore the dashboard** — Learn more about the [Aspire dashboard](/dashboard/overview/) and its features
+- **Learn about JavaScript support** — See [JavaScript support in Aspire](/whats-new/aspire-13/#javascript-as-a-first-class-citizen)
diff --git a/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx b/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx
index 141e44f87..2e3eee77e 100644
--- a/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx
+++ b/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx
@@ -1,947 +1,36 @@
---
-title: Aspireify an existing app
-description: Learn how to add Aspire orchestration to your existing application using aspire init.
+title: "Aspireify an existing app"
+description: "Choose an AppHost language for adding Aspire to an existing application."
+prev: false
+next: false
---
-import { Aside, Steps, FileTree, Tabs, TabItem } from '@astrojs/starlight/components';
-import { Kbd } from 'starlight-kbd/components'
+import { Aside, CardGrid, LinkCard } from '@astrojs/starlight/components';
import LearnMore from '@components/LearnMore.astro';
-import InstallPackage from '@components/InstallPackage.astro';
-import PivotSelector from '@components/PivotSelector.astro';
-import Pivot from '@components/Pivot.astro';
-
-
-This guide shows you how to add Aspire orchestration to an existing application, whether it's written in C#, Python, JavaScript, or a mix of these languages. Instead of starting from scratch, you'll use the `aspire init` command to incrementally adopt Aspire in your current project.
-
-:::note[Definition]{icon="approve-check-circle"}
-**Aspireify** (verb): To transform an existing application into a distributed, observable, and orchestrated system by adding Aspire—no cape required, just a few commands!
-:::
-
-## Why add Aspire to an existing app?
-
-As distributed applications grow, coordinating multiple services becomes a tangled web of configuration files, hard-coded URLs, and fragile startup scripts. You're juggling connection strings across environments, manually wiring service dependencies, and struggling to trace issues across your microservices. Development setup becomes a ritual of precision—start the database, then the cache, then service A before service B—and any misstep sends you back to square one.
-
-Aspire cuts through this complexity with a unified orchestration layer that treats your entire application as a cohesive system. Define your services and their relationships once in code ([the AppHost](/get-started/app-host/)), and Aspire handles service discovery, injects configuration automatically, and provides a dashboard with logs, traces, and metrics out of the box. Whether you're orchestrating C#, Python, or JavaScript services—or all three together—you get the same consistent experience from development through deployment.
-
-The best part? You can adopt Aspire incrementally. Start with orchestration, add observability when you're ready, integrate external services as needed. Your existing codebase stays largely unchanged, and you can reverse course if Aspire isn't the right fit.
-
-## Prerequisites
-
-Before you begin, ensure you have the following prerequisites installed based on your application's language:
-
-### Common requirements
-
-- [.NET SDK 10.0 or later](/get-started/prerequisites/) — Required for the Aspire AppHost, regardless of your application's language.
-- [Aspire CLI installed](/get-started/install-cli/) — For orchestration and deployment commands.
-- An existing application to add Aspire to.
-
-### Language-specific requirements
-
-
-
-**For C# applications:**
-
-- A solution with one or more .NET or ASP.NET Core projects (`.csproj`)
-- Visual Studio 2022 17.13 or later, Visual Studio Code, or JetBrains Rider (optional)
-
-**Example project types:**
-- ASP.NET Core Minimal API
-- ASP.NET Core Razor Pages or Blazor applications
-- Console applications
-- Worker services
-- gRPC services
-- Azure Functions
+When you add Aspire to an existing application, the first choice is the language of the AppHost. Choosing a C# or TypeScript AppHost lets you stay in a familiar toolchain while still using the AppHost to orchestrate services, define resources, and model relationships for the application you already have.
-
-
-
-**For Python applications:**
-
-- [Python 3.10 or later](https://www.python.org/downloads/) installed
-- [uv](https://docs.astral.sh/uv/) (recommended) or pip for package management
-- An existing Python application
-
-**Example application types:**
-- FastAPI web applications
-- Flask web applications
-- Django applications
-- Python scripts or worker processes
-- Streamlit or other Python web frameworks
-
-
-
-
-**For JavaScript/TypeScript applications:**
-
-- [Node.js 22 or later](https://nodejs.org/) installed
-- npm, yarn, or pnpm for package management
-- An existing JavaScript/TypeScript application
-
-**Example application types:**
-- React, Vue, or Svelte applications (especially Vite-based)
-- Node.js/Express APIs
-- Next.js applications
-- Angular applications
-- TypeScript backend services
-
-
-
-