Skip to content
Docs Try Aspire
Docs Try

YARP Serving Static Files

Aspire sample
TypeScript AppHost

Clone, run, and explore this sample

YARP reverse proxy serving a Vite frontend with dual-mode operation (dev HMR + production static files).

DockerNode.jsTypeScript
AppHost

The entry point that composes every resource and dependency in this sample's distributed application.

View on GitHub
apphost.mts
import { createBuilder } from "./.aspire/modules/aspire.mjs";
const builder = await createBuilder();
const executionContext = await builder.executionContext();
const dc = await builder.addDockerComposeEnvironment("dc");
const frontend = await builder.addViteApp("frontend", "./frontend");
await builder.addYarp("app")
.withConfiguration(async (yarp) =>
{
if (await executionContext.isRunMode())
{
const frontendCluster = await yarp.addClusterFromResource(frontend);
await yarp.addRoute("{**catch-all}", frontendCluster);
}
})
.withExternalHttpEndpoints()
.withBrowserLogs()
.publishWithStaticFiles(frontend)
.withComputeEnvironment(dc);
await builder.build().run();

YARP reverse proxy serving a Vite frontend with dual-mode operation (dev HMR + production static files).

Run Mode:

flowchart LR
    Browser --> YARP
    YARP --> Vite[Vite Dev Server<br/>HMR enabled]

Publish Mode:

flowchart LR
    Browser --> YARP[YARP serving<br/>Vite build output<br/>'npm run build']
  • addViteApp: Vite-based frontend application
  • addYarp: Reverse proxy with dual-mode routing
  • publishWithStaticFiles: Automatic static file serving in production
  • executionContext.isRunMode: Different behavior for dev vs production
  • Minimal AppHost: Single-file orchestration
Terminal window
aspire run
Terminal window
aspire run # Run locally
aspire deploy # Deploy to Docker Compose
aspire do docker-compose-down-dc # Teardown deployment

Dual-Mode YARP - Run mode proxies to Vite, publish mode serves static files:

import { createBuilder } from "./.aspire/modules/aspire.mjs";
const builder = await createBuilder();
const executionContext = await builder.executionContext.get();
const frontend = await builder.addViteApp("frontend", "./frontend");
await builder.addYarp("app")
.withConfiguration(async (yarp) =>
{
if (await executionContext.isRunMode.get())
{
const frontendCluster = await yarp.addClusterFromResource(frontend);
await yarp.addRoute("{**catch-all}", frontendCluster);
}
})
.publishWithStaticFiles(frontend);

Single Entry Point - YARP provides one external endpoint for the entire application

Preview

Sample screenshots

Select the image to zoom in.

Screenshot of the Vite primary page served through YARP in the YARP Serving Static Files sample
Screenshot of the Vite primary page served through YARP in the YARP Serving Static Files sample