0002. Preact 10 in the light DOM

Status: Accepted (2026-09-30)

Context

Every page redraws by assigning one HTML string to app.innerHTML, and renderKeepingPlace restores the focus and scroll each redraw loses. Every surveyed extension renders declaratively with a library that diffs. Whatever library Deckard picks ships in the VSIX, and shipped code is attack surface. Sizes below are esbuild 0.28, minified and gzipped.

Decision

Pages are TSX components rendered by Preact 10, into the light DOM, written against Preact’s own API. Preact is one package with no transitive dependencies, 4.6 kB per page, and it runs in the webview sandbox. It works under the nonce-only CSP with no unsafe-inline, uses native addEventListener, and renders in jsdom 30. esbuild compiles TSX natively, so tsc checks the markup with no plugin.

Two guards: pin 10.29.x exactly, since 11.0.0 shipped on 2026-09-30 with no track record; and never import preact/compat. @preact/signals is not adopted.

Consequences

Alternatives considered