Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions src/frontend/config/sidebar/docs.topics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,27 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = {
ja: 'コンテナー レジストリの構成',
},
},
{
label: 'Hot Reload and watch',
slug: 'app-host/hot-reload-and-watch',
translations: {
da: 'Hot Reload and watch',
de: 'Hot Reload and watch',
en: 'Hot Reload and watch',
es: 'Hot Reload and watch',
fr: 'Hot Reload and watch',
hi: 'Hot Reload and watch',
id: 'Hot Reload and watch',
it: 'Hot Reload and watch',
ja: 'Hot Reload and watch',
ko: 'Hot Reload and watch',
'pt-BR': 'Hot Reload and watch',
ru: 'Hot Reload and watch',
tr: 'Hot Reload and watch',
uk: 'Hot Reload and watch',
'zh-CN': 'Hot Reload and watch',
},
},
{
label: 'Eventing',
slug: 'app-host/eventing',
Expand Down Expand Up @@ -896,10 +917,10 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = {
},
},
{
label: 'Container files',
slug: 'app-host/container-files',
},
{
label: 'Container files',
slug: 'app-host/container-files',
},
{
label: 'Executable resources',
slug: 'app-host/executable-resources',
translations: {
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/scripts/check-data-files.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function checkDataFiles() {
console.log('\n🔄 Running update:all to generate missing files...\n');

try {
execSync('npm run update:all', { stdio: 'inherit' });
execSync('pnpm run update:all', { stdio: 'inherit' });
console.log('\n✅ Data files generated successfully');
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
Expand Down
193 changes: 193 additions & 0 deletions src/frontend/src/content/docs/app-host/hot-reload-and-watch.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
title: Hot Reload and watch
description: Learn how hot reload works in Aspire.
---

import { Tabs, TabItem } from '@astrojs/starlight/components';
import { Kbd } from 'starlight-kbd/components';

Aspire has two levels of watch behavior:

1. **AppHost watch** - watches the AppHost itself so changes to the application model restart the AppHost-managed application.
2. **Resource watch and hot reload** - depend on the application or framework backing each resource.

Aspire's CLI watch support is centered on the AppHost. Aspire supports two AppHost languages, C# and TypeScript, and `defaultWatchEnabled` applies to the AppHost-managed application regardless of which AppHost language you use.

When watch mode is enabled, Aspire owns the file-watching loop for the AppHost-managed application. File changes cause Aspire to restart the application topology so the updated AppHost model and resources are applied.

Aspire watch mode is the recommended CLI workflow when you want hot reload-like behavior for AppHost changes. It is restart-based: Aspire restarts the AppHost-managed application after changes instead of applying runtime-specific hot reload semantics inside every resource process.

## Default Aspire behavior

By default, `aspire run` and `aspire start` start the Aspire application once. They don't watch the AppHost or resource source files.

After you change AppHost code, restart the Aspire application manually:

- For `aspire run`, stop the process with <Kbd windows="Ctrl+C" mac="⌃+C" />, and then run `aspire run` again.
- For `aspire start`, run `aspire start` again. The command stops the previous detached instance and starts a new one.

## Enable default watch mode

Aspire includes an opt-in `defaultWatchEnabled` feature flag. When enabled, Aspire uses watch mode by default and automatically restarts the Aspire application after supported AppHost or resource file changes:

```bash title="Aspire CLI"
aspire config set features.defaultWatchEnabled true
```

To enable watch mode for every Aspire project on your machine, set the value globally:

```bash title="Aspire CLI"
aspire config set features.defaultWatchEnabled true --global
```

To see the current value and available feature flags, run:

```bash title="Aspire CLI"
aspire config list --all
```

Watch mode is useful when you want Aspire to restart the AppHost-managed application for you after AppHost changes. It supports both C# and TypeScript AppHosts and is a restart-based workflow, not the same experience as runtime-specific or IDE-specific hot reload.

## AppHost language guidance

<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>

For a C# AppHost, `defaultWatchEnabled` watches the AppHost project. When AppHost code changes, Aspire restarts the AppHost-managed application so the updated model is applied.

Today, C# project resources are also controlled by this setting. That means changes to C# project resources can trigger Aspire to restart the AppHost-managed application too.

Use this workflow when changes affect:

- The AppHost model in `AppHost.cs`.
- C# project resources that are part of the AppHost.
- Resource configuration, endpoints, parameters, or integration setup.
- Multiple services that need to be restarted together under Aspire orchestration.

```bash title="Aspire CLI"
aspire config set features.defaultWatchEnabled true
aspire run
```

</TabItem>
<TabItem id='typescript' label='TypeScript'>

For a TypeScript AppHost, `defaultWatchEnabled` watches the AppHost. When AppHost code changes, Aspire restarts the AppHost-managed application so the updated model is applied.

TypeScript AppHost watch doesn't automatically provide hot reload for every resource in the application. Use resource-specific watch, reload, restart, or rebuild workflows for changes inside individual resources.

Use this workflow when changes affect:

- The AppHost model in `apphost.ts`.
- Resource configuration, endpoints, parameters, or integration setup.
- Multiple services that need to be restarted together under Aspire orchestration.

```bash title="Aspire CLI"
aspire config set features.defaultWatchEnabled true
aspire run
```

</TabItem>
</Tabs>

## Hot reload for Aspire resources

AppHost watch and resource hot reload are separate concerns. The AppHost describes and starts the application topology, but each resource is backed by a framework or runtime with its own development loop.

In general, keep the AppHost running while you work on individual resources. Don't stop and restart the AppHost just because one resource changed. If a resource needs to be restarted or rebuilt, do that for the individual resource from the Aspire CLI or the Aspire Dashboard.

Use the `aspire resource` command to control individual resources from the CLI:

```bash title="Aspire CLI"
aspire resource <resource-name> stop
aspire resource <resource-name> start
```

For C# project resources, rebuild the individual resource when the project needs to be rebuilt:

```bash title="Aspire CLI"
aspire resource <resource-name> rebuild
```

<Tabs syncKey='resource-watch'>
<TabItem label='C# projects'>

`dotnet watch` natively supports C# Aspire AppHosts and transitively watches .NET projects in the application:

- Changes to the AppHost restart the AppHost.
- Changes to an individual .NET project, or to one of its dependencies, restart that project.
- Rude edits restart the application.

Run `dotnet watch` against the AppHost project when you want the .NET SDK's watch loop for the AppHost and its C# projects:

```bash title=".NET CLI"
dotnet watch --project './src/MyApp.AppHost/MyApp.AppHost.csproj'
```

:::note[Important]
This experience has some quirks today. Some changes are applied but can still require an explicit restart, and it isn't always easy to tell when that happened. If you don't observe an expected change, restart the resource with `aspire resource <resource-name> stop` and `aspire resource <resource-name> start`, or rebuild a C# project resource with `aspire resource <resource-name> rebuild`.
:::

When you use Aspire watch mode instead, C# project resources are special today: `defaultWatchEnabled` controls both the C# AppHost and C# project resources.

</TabItem>
<TabItem label='Vite resources'>

Vite resources use Vite's development server behavior. Vite can provide browser refresh and Hot Module Replacement for the frontend application, but that behavior is separate from AppHost watch.

Use Aspire watch when changes affect the AppHost model. Use the Vite development loop when changes affect the frontend application and you want Vite's browser refresh or Hot Module Replacement behavior.

If a Vite resource needs a restart, restart the Vite resource from the Aspire CLI or dashboard instead of restarting the AppHost.

</TabItem>
<TabItem label='Other resources'>

Other Aspire resources follow the watch, reload, or restart behavior of the runtime or framework that backs the resource. For example, a container resource, executable resource, or framework-specific resource might not support hot reload at all, or it might require its own watch command.

Use Aspire watch when the AppHost model should be re-evaluated. Use the resource's native development command when you want the tightest inner loop for that resource. If the resource needs to be restarted or rebuilt, restart or rebuild that individual resource from the Aspire CLI or dashboard.

</TabItem>
</Tabs>

## Recommended workflow

Use these workflows based on what you're editing:

| Goal | Recommended command |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| Run the whole distributed app once | `aspire run` |
| Run the whole distributed app in the background | `aspire start` |
| Watch a C# or TypeScript AppHost from the CLI | `aspire config set features.defaultWatchEnabled true`, then `aspire run` or `aspire start` |
| Watch C# project resources through Aspire | `aspire config set features.defaultWatchEnabled true`, then `aspire run` or `aspire start` |
| Restart one resource | `aspire resource <resource-name> stop`, then `aspire resource <resource-name> start` |
| Rebuild one C# project resource | `aspire resource <resource-name> rebuild` |
| Use a runtime-specific hot reload loop for one resource | The resource's native watch, reload, or development-server command |

Aspire CLI doesn't currently provide a single hot reload command that applies every runtime's hot reload semantics across an AppHost-managed distributed application. Aspire default watch supports both AppHost languages by restarting the AppHost-managed application after AppHost changes. C# project resources are also controlled by this setting today. For other resources, keep the AppHost running and use the resource's framework, runtime, CLI action, or dashboard action for resource-specific reloads, restarts, and rebuilds.

## IDE hot reload and debugging

Visual Studio, Visual Studio Code, and JetBrains Rider provide their own hot reload and debugging experiences. When you run the AppHost under a debugger in one of these IDEs, Aspire delegates debugging and IDE-managed hot reload behavior to that IDE. This doesn't integrate with or overlap Aspire's CLI restart, rebuild, or watch behavior.

:::note[Important]
Use an IDE workflow when you want the IDE to manage debugging or hot reload for supported resources. Use Aspire CLI and dashboard actions when you want Aspire to restart, rebuild, or watch the AppHost-managed application and its resources.
:::

### Visual Studio Code

Use the Aspire extension for Visual Studio Code when you want VS Code to start the AppHost, attach debuggers, and manage supported resource debugging experiences. VS Code hot reload or framework-specific refresh behavior still belongs to the debugger or framework backing the resource, not to Aspire restart, rebuild, or watch behavior.

### Visual Studio

Use Visual Studio when you want its built-in debugging and hot reload experience for supported resources. Visual Studio can run and debug Aspire apps, but IDE hot reload is still separate from Aspire restart, rebuild, and watch behavior.

### JetBrains Rider

Use JetBrains Rider when you want Rider's debugging and hot reload experience for supported resources. Rider's IDE-managed hot reload behavior is separate from Aspire restart, rebuild, and watch behavior.

## See also

- [`aspire run`](/reference/cli/commands/aspire-run/)
- [`aspire start`](/reference/cli/commands/aspire-start/)
- [`aspire config set`](/reference/cli/commands/aspire-config-set/)
- [Aspire VS Code extension](/get-started/aspire-vscode-extension/)
15 changes: 11 additions & 4 deletions src/frontend/src/content/docs/dashboard/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import FeatureShowcase from '@components/FeatureShowcase.astro';
import ImageShowcase from '@components/ImageShowcase.astro';
import CapabilityGrid from '@components/CapabilityGrid.astro';
import CTABanner from '@components/CTABanner.astro';

import OsAwareTabs from '@components/OsAwareTabs.astro';

import projectsImage from '@assets/dashboard/explore/resources-filtered-containers.png';
Expand Down Expand Up @@ -74,7 +73,15 @@ The Aspire Dashboard is your command center during development. Powered by [Open

## Run the dashboard standalone

The dashboard starts automatically with your Aspire app, but it can also run standalone as a Docker container to monitor any application that sends OpenTelemetry data. Start it with a single command:
The dashboard starts automatically with your Aspire app, but it can also run standalone to monitor any application that sends OpenTelemetry data.

Install the Aspire CLI, then start the dashboard:

```bash title="Aspire CLI"
aspire dashboard run
```

Or run the same standalone dashboard from its container image:

<OsAwareTabs syncKey="terminal">
<div slot="unix">
Expand All @@ -95,7 +102,7 @@ docker run --rm -it -p 18888:18888 -p 4317:18889 -p 4318:18890 -d --name aspire-
</div>
</OsAwareTabs>

Navigate to `http://localhost:18888` to open the dashboard, and point your apps' OTLP exporter to `http://localhost:4317`. For more details, see the [standalone dashboard guide](/dashboard/standalone/).
Open the dashboard URL, then point your apps' OTLP exporter to `http://localhost:4317`. For prerequisites, login details, and additional options, see the [standalone dashboard guide](/dashboard/standalone/).

## AI-powered debugging

Expand Down Expand Up @@ -151,7 +158,7 @@ Navigate to `http://localhost:18888` to open the dashboard, and point your apps'
icon: 'laptop',
title: 'Standalone mode',
description:
'Use the dashboard independently as a Docker container to monitor any application that sends OpenTelemetry data.',
'Use the dashboard independently to monitor any application that sends OpenTelemetry data.',
href: '/dashboard/standalone/',
},
]}
Expand Down
32 changes: 1 addition & 31 deletions src/frontend/src/content/docs/dashboard/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ description: Overview of Aspire dashboard and getting started.
---

import { Image } from 'astro:assets';
import OsAwareTabs from '@components/OsAwareTabs.astro';
import ThemeImage from '@components/ThemeImage.astro';
import projectsImage from '@assets/dashboard/explore/projects.png';
import architectureDiagramDark from '@assets/dashboard/architecture-diagram-dark.svg';
Expand All @@ -31,36 +30,7 @@ For more information about using the dashboard during Aspire development, see [E

## Standalone mode

The Aspire dashboard is also shipped as a Docker image and can be used standalone, without the rest of Aspire. The standalone dashboard provides a great UI for viewing telemetry and can be used by any application.

<OsAwareTabs syncKey="terminal">
<div slot="unix">

```bash
docker run --rm -it -p 18888:18888 -p 4317:18889 -p 4318:18890 -d --name aspire-dashboard \
mcr.microsoft.com/dotnet/aspire-dashboard:latest
```

</div>
<div slot="windows">

```powershell
docker run --rm -it -p 18888:18888 -p 4317:18889 -p 4318:18890 -d --name aspire-dashboard `
mcr.microsoft.com/dotnet/aspire-dashboard:latest
```

</div>
</OsAwareTabs>

The preceding Docker command:

- Starts a container from the `mcr.microsoft.com/dotnet/aspire-dashboard:latest` image.
- The container instance exposing three ports:
- Maps the dashboard's port `18888` to the host's port `18888`. Port `18888` has the dashboard UI. Navigate to `http://localhost:18888` in the browser to view the dashboard.
- Maps the dashboard's OTLP/gRPC port `18889` to the host's port `4317`. Port `4317` receives OpenTelemetry data from apps using [OTLP/gRPC](https://opentelemetry.io/docs/specs/otlp/#otlpgrpc).
- Maps the dashboard's OTLP/HTTP port `18890` to the host's port `4318`. Port `4318` receives OpenTelemetry data from apps using [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/#otlphttp).

For more information, see the [Standalone Aspire dashboard](/dashboard/standalone/).
The Aspire dashboard can run standalone, without the rest of Aspire. The standalone dashboard provides a great UI for viewing telemetry and can be used by any application that sends OpenTelemetry data. You can start it with the Aspire CLI or run it from the standalone container image. For more information, see the [Standalone Aspire dashboard](/dashboard/standalone/).

## Configuration

Expand Down
Loading
Loading