Snapshot 2026-09-11
Module · Level 1

Security

A restricted, non-eval() expression language and statically-resolved property access remove whole classes of injection risk. It does not, by itself, make an untrusted component definition safe: that needs its own trust model.

Level 1 · normative

What that looks like in practice: expressions never run as code, and dangerous sinks are unreachable by a binding.

<!-- Blocked: no expression is ever eval'd; a bound javascript: URL is dropped -->
<a :href="user.website"></a>       <!-- javascript:… as the value → attribute removed -->
<button onclick="…">                 <!-- inline handler → non-conforming, rejected -->

<!-- Allowed: markup output goes through the sanitizer, never a raw string sink -->
<article $html="post.body">          <!-- parsed + sanitized: <script>/on*/javascript: stripped -->

Requirements

  1. The compiler and runtime must not evaluate source through eval(), new Function(), or equivalent. Contract JSON is data; expressions are parsed by HTML Next (the restricted expression language).
  2. Raw dynamic HTML is not permitted at Level 1. Markup output goes through the sanitizer via $html (see Templating); future URL, style, and HTML-valued sinks must define contextual validation and escaping.
  3. A restricted expression language reduces code-execution risk but does not make untrusted component definitions safe; data-source permissions, untrusted imports, and controller code need separate models.
  4. Property resolution uses a generated static manifest keyed by ASCII-lowercase name, never runtime prototype enumeration, and must reject two properties that collapse to the same key rather than pick a winner.
Not a sandbox

Restricting the expression language is a hardening measure, not an isolation boundary. Running someone else's component still requires deciding what its definition may reach and whether to load its code. The concrete gates, CSP for controllers, modulepreload integrity for pinning, and the open per-controller allowlist, are described in The JavaScript Layer.