Clone, run, and explore this sample
YARP reverse proxy serving a Vite frontend with dual-mode operation (dev HMR + production static files).
AppHost
The entry point that composes every resource and dependency in this sample's distributed application.
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).
Architecture
Section titled ArchitectureRun 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']What this demonstrates
Section titled What this demonstrates- 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
Running
Section titled Runningaspire runCommands
Section titled Commandsaspire run # Run locallyaspire deploy # Deploy to Docker Composeaspire do docker-compose-down-dc # Teardown deploymentKey aspire patterns
Section titled Key aspire patternsDual-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.