Architecture: How to implement live in-browser preview of generated Angula...

Documentation for Sessions

🏗️ Architecture: How to implement live in-browser preview of generated Angula...

Date: 2026-03-11
Time: 23:36:35 UTC
Session: gspace1-205.2
Agent: angular
Confidence: 88%
Status: ✅ Documented


📋 Decision Context

Question:

How to implement live in-browser preview of generated Angular platforms without WebContainers (commercial license) or cloud compilation servers?

Task: Not specified


🎯 Decision Made

Chosen:

@rspack/browser (v1.7.2) — Rust bundler compiled to WASM, running entirely in the browser with builtinMemFs for in-memory filesystem, BrowserHttpImportEsmPlugin resolving @angular/* from esm.sh CDN, and a dedicated Service Worker serving compiled output at /_preview/{sessionId}/*

Options Considered:

  1. WebContainers (@webcontainer/api) — StackBlitz's solution, full Node.js in browser, but commercial license required for production
  2. @rspack/browser — Rust WASM bundler, MIT license, experimental but fast, in-memory FS
  3. Cloud compilation server — backend runs ng build and streams result back, adds latency and server cost
  4. Sandpack (CodeSandbox) — browser bundler but limited Angular support, no SCSS
  5. Dev server iframe — just ng serve the generated code and iframe it, simple but requires server process

💭 Reasoning

WebContainers requires a commercial license for production use. Cloud compilation adds latency and infrastructure cost. Sandpack has poor Angular 20 support. @rspack/browser is MIT-licensed, compiles Rust to WASM for near-native speed, has builtinMemFs for zero-IO compilation, and BrowserHttpImportEsmPlugin for CDN-based dependency resolution. The Service Worker approach (separate scope at /_preview/) serves compiled assets with proper Content-Type headers, enabling proper module resolution and routing — unlike srcdoc which breaks relative imports. Fallback to WebContainers is trivial since both use a BundlerProvider abstraction. CRITICAL DISCOVERY: @rspack/browser uses top-level await in its WASI loader, which esbuild (used by Angular dev server) rejects. Solution: dynamic import via variable (const modulePath = '@rspack/browser'; await import(modulePath)) prevents esbuild from statically resolving it. Also, the library needs explicit RspackMemFs interface typing since builtinMemFs is synchronous but wrapped in an async import.


📁 Files Involved


🔗 Related


Auto-generated by MCP Smart Consolidation