microsoft / microsoft/aspire.dev

Document JavaScript framework publish methods (PublishAsStaticWebsite, PublishAsNodeServer, PublishAsNpmScript, AddNextJsApp)

Open
#673 2 comments 0 reactions 1 assignee View on GitHub

@IEvangelist is already working on this.

Since Jun 2, 2026.

enhancement
Dominant language
MDX
Stars
193
Forks
87
Avg merge
1d 22h
Merged PRs (30d)
73

Description

## Summary

PR [microsoft/aspire#15736](https://github.com/microsoft/aspire/pull/15736) added new JavaScript publish methods and `AddNextJsApp` to `Aspire.Hosting.JavaScript`. We need a comprehensive article covering how to use JavaScript frameworks with Aspire — from local development through deployment.

## Proposed article: "Using JavaScript frameworks with Aspire"

### Topics to cover

#### 1. Framework categories and which publish method to use

| Category | Publish Method | Frameworks | Why |
|----------|---------------|------------|-----|
| Static SPAs | `PublishAsStaticWebsite` | Vite, React, Vue, Angular, Astro (static) | Build outputs static `dist/` files, served by YARP |
| Self-contained Node servers | `PublishAsNodeServer` | SvelteKit, TanStack Start | Build bundles everything, runs with `node server.js` |
| Node servers needing node_modules | `PublishAsNpmScript` | Nuxt, Remix, Astro SSR | Runtime imports from `node_modules` |
| Next.js | `AddNextJsApp` | Next.js | Standalone output with 3-COPY Dockerfile pattern |

#### 2. Local development (run mode)

- `AddViteApp` vs `AddJavaScriptApp` vs `AddNodeApp` vs `AddNextJsApp` — when to use each
- Port binding: how Aspire passes `--port` (Vite) vs `-p` (Next.js) to dev servers
- Package managers: `WithNpm()`, `WithYarn()`, `WithPnpm()`, `WithBun()` — composable with all methods
- `WithOtlpExporter()` — getting telemetry from JS apps into the Aspire dashboard

#### 3. Publishing / Deployment

- `PublishAsStaticWebsite` — YARP-based static file serving
- Default behavior (SPA fallback, `dist/` output)
- `outputPath` for Angular (`dist/browser`) and other frameworks
- API reverse-proxy with `apiPath`/`apiTarget` (solves CORS for SPAs)
- `StripPrefix` option
- `TargetEndpointName` for specific endpoint selection
- `PublishAsNodeServer` — self-contained Node.js server
- `entryPoint` and `outputPath` parameters
- Framework-specific examples (SvelteKit `build/index.js`, TanStack `.output/server/index.mjs`)
- `PublishAsNpmScript` — runtime with node_modules
- When to use (Nuxt's `useAsyncData`, Remix's `react-router-serve`, Astro SSR's `@astrojs/*`)
- `startScriptName` and `runScriptArguments`
- `AddNextJsApp` — Next.js standalone
- `output: "standalone"` in `next.config.ts` (required)
- `public/` directory requirement
- Deploy-time validation and `DisableBuildValidation()`

#### 4. Framework-specific gotchas

Based on [aspire-js-chaos](https://github.com/davidfowl/aspire-js-chaos) POC validation:

- **Nuxt**: Pages must be under `app/pages/`, env vars need `NUXT_` prefix for `runtimeConfig`
- **Astro SSR**: Must set `export const prerender = false`, use `process.env` not `import.meta.env`
- **SvelteKit**: Requires `@sveltejs/adapter-node` (default `adapter-auto` doesn't produce a deployable artifact)
- **Next.js**: Must set `output: "standalone"`, needs `public/` directory
- **Angular**: Uses `dist/browser` output path, not `dist`

#### 5. Advanced scenarios

- Custom base images via `WithDockerfileBaseImage`
- `PublishWithContainerFiles` for embedding static files into a .NET server (existing pattern)
- How to choose between `PublishAsStaticWebsite` + API proxy vs `PublishWithContainerFiles`

### Related

- Feature PR: https://github.com/microsoft/aspire/pull/15736
- Issue: https://github.com/microsoft/aspire/issues/12697
- POC repo: https://github.com/davidfowl/aspire-js-chaos
- Existing docs page to update/replace: https://aspire.dev/deployment/javascript-apps/

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.