Compile-time
No Proxy, no Virtual DOM. The compiler emits surgical DOM updates — it knows exactly which node depends on which value.
Reactivity is resolved at compile time. Components are native Web Components with their own Shadow DOM. Deep reactivity by default, and SSR included.
No Proxy, no Virtual DOM. The compiler emits surgical DOM updates — it knows exactly which node depends on which value.
0.99× Svelte 5 on the official benchmark, ~24 KB brotli (~27 KB gzip), and ~15 ms for 1M deep mutations. No runtime Proxy overhead.
Each component is a Custom Element with its own Shadow DOM. No proprietary runtime — just the platform.
This counter is a live MJS component. Reactivity is compiled — clicking updates only the number, nothing else.
<script> $count = 0 inc = -> $count++ </script> <button @click={inc}> Clicks : {$count} </button>
Nested objects and arrays track automatically.
Render-then-replace, Declarative Shadow DOM.
Built-in transitions and FLIP animations.
A client-side router, batteries included.
Global state with $$ stores and § context.
<@module> mounts a component by name.
Reusable markup fragments and named slots.
<@failed> catches errors and shows a fallback.
| Criterion | MJS | Svelte | React | Solid |
|---|---|---|---|---|
| Approach | compile-time | compile-time | VDOM | compile-time |
| Runtime | ~24 KB | ~10 KB | ~45 KB | ~7 KB |
| Deep reactivity, no Proxy | ✓ | partial | no | manual |
| Native Web Components | ✓ | no | no | no |
| SSR | ✓ | ✓ | ✓ | ✓ |
Figures are indicative and meant to be honest, not promotional.
One command to get the framework.
npm install mjs-framework