Vue Compatibility

Lune uses Vue-style template syntax and a port of Vue's reactivity package, but it is not the full Vue runtime. Use this page to check which Vue features are supported, partially supported, or intentionally omitted.

Supported

FeatureNotes
InterpolationText interpolation with {{ }} or custom delimiters.
lu-scopeCreates a reactive scope for an element.
lu-if, lu-else-if, lu-elseConditional rendering.
lu-forArrays, objects, numbers, and basic destructuring.
lu-modelText inputs, textareas, checkboxes, radios, and selects.
lu-bind / :Attribute, class, style, object, and :ref bindings.
lu-on / @DOM event listeners, common modifiers, key modifiers, and @lune:mounted / @lune:unmounted.
lu-showToggles inline display.
lu-text, lu-html, lu-cloak, lu-pre, lu-onceSupported as lightweight directives.
refStores DOM elements on $refs.
reactive()Re-exported from @lune-js/core, a port of @vue/reactivity built on Alien Signals.
effect()Re-exported from @lune-js/core; returns the effect runner.

Different from full Vue

AreaLune behavior
ComponentsComponents are plain functions or objects returned from lu-scope; there are no SFCs, render functions, props validation, emits, slots, or setup().
Refsref stores DOM elements, including elements that also have lu-scope. It does not return a Vue component instance.
Reactivity exportsreactive(), readonly(), shallowReactive(), shallowReadonly(), effect() and nextTick() are exported from lune-js. There is no ref(), computed(), watch() or effectScope() — use getters for derived values and effect() for side effects, or install @vue/reactivity alongside Lune.
Event listeners@event listeners are attached to DOM elements. app.unmount() stops reactive effects and directive cleanup callbacks, but native event listeners remain attached until the DOM elements are removed or the browser releases them.
ExpressionsTemplate expressions are parsed and compiled by Lune's own engine rather than new Function(), so Lune runs under a Content Security Policy without unsafe-eval. The engine implements a subset of JavaScript and resolves identifiers against an allow list — see Security.
Mountingapp.mount(selector) returns undefined if the selector does not match an element.

Unsupported Vue syntax

Vue featureWhat to use instead
Single-file components (.vue)Plain HTML plus lu-scope objects/functions.
createApp(Component) root componentscreateApp(initialData).mount(target).
setup(), data(), methods, computed optionsReturn or pass a plain object with fields, methods, and JavaScript getters.
props, emits, provide / injectPass values through functions, parent scopes, or shared reactive stores.
Slots and scoped slotsUse normal HTML/template fragments and lu-scope functions.
TransitionsUse CSS and lifecycle events manually.
lu-on="object"Use individual event bindings like @click="onClick".
Full Vue app config/pluginsLune plugins only receive the app instance and can register directives or mutate app state.
Loops, function/class, async/await inside expressionsKeep that logic in a scope method, where it is ordinary JavaScript.
Browser globals inside expressionsRegister what the template needs with allowGlobals(), or pass it through the scope.

When to choose full Vue instead

Use full Vue if you need SFCs, router-driven SPA behavior, rich component contracts, SSR hydration, or the full Composition API from the vue package.