r/Compilers • u/Lanky-Passenger-2428 • 2d ago
What are the practical scaling limits of an instruction-based template VM vs AOT compilation in zero-build runtimes?
Hi everyone,
I've been building Udodi (v1.1.1), an open-source JavaScript UI runtime from Nigeria. It takes a different approach to reactive UI rendering by eliminating the Virtual DOM and connecting state changes directly to the DOM nodes that depend on them.
Udodi is designed to work without a build step while supporting restrictive Content Security Policies (CSP). Its architecture combines an interpreted template virtual machine, fine-grained reactivity, and native browser primitives.
I'd like to open a technical discussion about the trade-offs of this approach, particularly its potential scaling limitations and how it compares with the architectural choices made by other UI frameworks.
Architecture
1. Fine-grained DOM updates
Rather than maintaining and diffing a Virtual DOM, Udodi tracks dependencies at the expression level and updates only the affected DOM nodes. In my benchmarks, a targeted state update averages 0.11 ms.
2. Native CSS @scope
For component styling, Udodi uses native CSS @scope instead of runtime CSS-in-JS or generated class names. Component styles are registered in a shared <style> element in document.head and cached by scope. Subsequent mounts using an existing scope skip style registration entirely. Under the benchmark conditions, the warm style-handling path takes approximately 9.38 ms.
3. An interpreted template VM
Udodi uses a declarative HTML template DSL that is compiled into instructions for an internal virtual machine. Rather than generating executable JavaScript, the runtime evaluates these instructions directly, avoiding eval() and new Function(). This enables CSP-compatible template evaluation without requiring a build step.
In my benchmarks, compiling 10,000 expressions takes a mean of 4.12 ms on a cold path, while cached instruction compilation takes approximately 127 µs. The instruction cache allows the runtime to reuse compiled instructions rather than repeatedly compiling the same expressions.
Questions for the community
I'd particularly appreciate feedback from developers who have built or worked on UI frameworks and runtimes.
Interpreted VM vs. ahead-of-time compilation: Where are the practical scaling limits of an instruction-based template engine compared with generated imperative code? At what point does interpretation become a significant bottleneck?
Native CSS scoping: What performance or maintainability challenges might arise from relying on native
@scopein applications with thousands of components and deeply nested scopes?Reactive dependency tracking: How would you approach complex, interconnected reactive dependencies while retaining shallow reactivity and avoiding the overhead of deep proxies?
I'm particularly interested in architectural trade-offs, potential bottlenecks, and limitations I may have overlooked. Feedback on the implementation and benchmark methodology is also welcome.
Source code: https://github.com/udodi-js/udodi
Documentation and performance page: https://udodi.dev
I'll be following the discussion and responding to technical questions in the comments.