Vapor Mode v0.6
Vapor mode is Vue's compilation-based rendering mode (Vue 3.6): templates compile to code that manipulates elements directly — no Virtual DOM, no per-component diffing. Vue Lynx runs it on Lynx's dual-thread architecture. On the update path it is 5.8–9.8× faster on the background thread than VDOM (2.1–6.3× end-to-end), with creation at parity and roughly half the cross-thread traffic, for about +26% bundle gzip — full numbers (and an interactive playground; ReactLynx as reference) in the framework bench.
Vapor mode itself is not part of any stable Vue release yet — as of
mid-2026 it ships only in the Vue 3.6 beta / prerelease line. Vue Lynx pins
vue@3.6.0-beta.17 and inherits that status.
Enabling Vapor mode
Vapor is a per-app, build-time choice. Turn it on in three places: the
plugin flag, the vue-lynx/vapor entry, and the vapor attribute on each
<script setup>:
import { ref } from 'vue' keeps working — with vapor: true the plugin
aliases 'vue' to vue-lynx/vapor. That entry is the Vapor runtime plus
Lynx DOM-compat layer (not the default vue-lynx VDOM entry). Full export
list: vue-lynx/vapor API reference.
The demo below is the repository's Vapor example — same three changes, live on this page:
This site can flip many examples between VDOM and Vapor with the VDOM | Vapor control in the nav (and the badge in each example's footer). Coverage and unsupported reason codes are listed in the example support appendix.
Instant first-frame rendering
Vapor in 0.6 supports
Instant First-Frame Rendering (IFR) — paint synchronous content
during loadTemplate before the background thread starts. Enable it next to
vapor:
Vapor IFR uses the compiled template() / tree protocol (not VDOM Element
Templates). Product thesis and enablement:
IFR · measured trade-offs:
IFR benchmarks.
Limitations
Same as upstream Vapor
These match Vue's Vapor constraints today:
- No Options API —
<script setup>only;getCurrentInstance()returnsnull. - Not yet shipped upstream:
<Transition>,<Teleport>,<KeepAlive>,<Suspense>, and other VDOM-only APIs (h(), …). They are absent fromvue-lynx/vaporand fail at build time if used by mistake.
Lynx also has no HTML string surface, so v-html and SSR / HTML hydration
are unavailable (same as VDOM-mode Vue Lynx). Dual-thread
IFR hydration is a separate mechanism.
One app, one mode
Vue Lynx does not mix VDOM and Vapor in the same app (vaporInteropPlugin is
not wired up — upstream ties it to the browser DOM renderer). Mode is a
strict either/or, so Vue Lynx ships two pure entries instead of one entry
pruned by tree-shaking:
Appendix
How it works on Lynx
Upstream @vue/runtime-vapor expects a DOM. Vue Lynx gives the background
thread a DOM-compatible ShadowElement surface; compiled Vapor code calls
normal DOM APIs, which emit the same ops stream to the main thread as VDOM
mode:
Lynx-specific bits: template strings become cloneable prototypes; document
event delegation is off (per-element events); @tap.stop maps to
catchEvent; scoped CSS uses scope classes instead of data-v-*.
To keep clone-heavy lists cheap across threads, Vue Lynx adds two ops:
REGISTER_TREE— static structure once per templateCLONE_TREE— one op per instance (uids assigned the same way on both threads)
On create-1k that cuts traffic from ~17k ops / 327 KB (VDOM) to ~7k ops / 160 KB (Vapor).
Example support
Every example on this site is checked against both renderers. Unsupported reason codes map to the limitations above.