docs / Compiler

Static Code Generation

How the client codegen distinguishes fully-static subtrees from reactive ones, and how hydrate-mode markers work.

The client codegen distinguishes fully-static subtrees from reactive ones at compile time. Static subtrees are constructed once and never touched by effects; reactive subtrees get per-cell DOM update wiring.

isStaticIR

  • `isStaticIR(body)` returns true only when every node is a StaticNode or TextNode and no attribute binding (including on* handlers) is dynamic.
  • A component whose whole body is static gets no effect wiring — its DOM is built once, synchronously.
  • A component with a `<style>` block is never static.
  • A MapRegion counts as static only when both its template and alternate are static.

Hydrate-mode markers

subtreeNeedsJS
									
										subtreeNeedsJS = __vskHydrate && (forceClaim || !isStaticIR(node.children))
									
								
  • Static subtrees: no marker, no client-side reconstruction — the server HTML is claimed as-is.
  • Reactive subtrees: a `<!--vsk-->` marker tells the client hydrator where to attach effects and per-cell update code.
  • forceClaim forces a claim marker even for a static-looking subtree (e.g. event delegation).

Static props

Module-level `export const props = { ... }` static data is hoisted into IRRoot.staticProps and re-emitted once, shared by server and client outputs instead of being re-evaluated per component.