# 04 — Render spike: embedding the genuine Excalidraw component in a DSH client plugin **Task:** task-3 — decide, empirically, whether the DSH Excalidraw plugin should embed the real `@excalidraw/excalidraw` React component or fall back to a custom lightweight canvas editor. **Verdict: EMBED the genuine component.** It bundles, mounts, draws, exports and survives the DSH `window.__ModuleLoader__` contract — including on the **React 18.3.1** that the live DSH shell actually seeds. The measured costs are bundle size (mitigable by chunking) and one small host-side route for `.woff2` fonts. No blocking incompatibility was found. | Question | Answer | | --- | --- | | Bundles with esbuild into one self-contained classic script? | **Yes** — 8.01 MiB raw / 2.39 MiB gzip with React external; React is not embedded | | Mounts and paints in real Chrome? | **Yes** — 19/19 standalone assertions, 28/28 DSH-contract assertions | | Real mouse/keyboard drawing + scene read-back? | **Yes** — rectangle, arrow and text created via input events; scene JSON read through the API | | Imperative API works? | **Yes** — `updateScene`, `getSceneElements`, `getAppState`; exports are package-level (`exportToSvg`/`exportToBlob`), not on the instance | | `convertToExcalidrawElements` bindings? | **Yes** — arrow `start`/`end` bindings become real `startBinding`/`endBinding` + `boundElements` | | Works through the DSH loader wrapper with page-supplied React? | **Yes** — require(`react`) resolves from the module table; component reports React 18.3.1 | | CSP / worker / font / ResizeObserver blockers? | **None** on the real DSH page (no CSP). Strict-CSP behaviour and the hardcoded esm.sh fallback are documented below | | Trailing risk | Bundle size + font route; chunked build recommended | Evidence: [`docs/evidence/render/`](evidence/render/) — screenshots, assertion JSON, network/console logs, canonical element JSON, bundle size report. --- ## 1. Method The spike is deliberately outside `src/` and does not install anything into the live DSH profile. Everything lives under [`spikes/render/`](../spikes/render/): ``` spikes/render/ package.json React 19.2.0 (standalone), React 18.3.1 (DSH harness alias), @excalidraw/excalidraw 0.18.1, playwright-core 1.56.0, esbuild 0.28.1 src/standalone.js React 19 page: Excalidraw mount + CSS/font injection + lib surface src/dsh-entry.js DSH plugin module (inject/apply) + tagged