Differences from Vue 3
Decagrammaton uses Vue 3 SFC syntax, but compiles to the Ark of Atrahasis safe DOM inside an SES sandbox. Anything that can't be expressed as a whitelisted Ark call is rejected at build time with a DecaCompileError — nothing fails silently.
If you know Vue 3, this page is the short list of what's missing or restricted.
Templates
- Single-element roots for
v-if/v-for. Av-ifbranch orv-forrow must have exactly one root element/component — no fragments, no bare text, no sibling roots. (A component template itself may have multiple sibling roots —<template><div/><div/></template>— and so may the app root. Only branch/row bodies are restricted.) - A component must render at least one node. An empty
<template>(zero roots) is rejected — there is no placeholder node to hold its position. - No
<template>grouping. You can't wrap av-if/v-forgroup in a<template>tag — use a real element (e.g.<div>). - Whitelisted tags only. Every tag maps to an Ark creator. An unknown tag (e.g.
<marquee>) has no creator and fails the build. - Whitelisted attributes only. There is no generic
setAttribute— each attribute maps to a specific Ark setter. An unmapped attribute fails the build. - No dynamic attribute or event names —
:[attr]="x"and@[event]="h"throw (nothing to whitelist at build time). - Inline handlers must be expressions.
@click="() => { a(); b(); }"(block body) throws — move it into a method.
Components
- No events /
emit. There is nodefineEmitsoremitchannel. Use a callback prop instead (:onAdd="addTask"). - No component
v-model/defineModel. Two-way binding only works on native<input>/<textarea>/<select>. - Props are read-only, one-way. Assigning to a prop throws. Signals passed as props arrive unwrapped; use a
deepSignalto share mutable state. - Default slot only. No named slots, no scoped slots, no slot forwarding.
- No dynamic components (
<component :is="...">). - No built-ins: no
<Teleport>,<Suspense>,<KeepAlive>,<Transition>.
Reactivity & API
provide/injectare real imports fromdecagrammaton, not macros — and are setup-only.- No root
app.provide()— provide/inject works at the component-instance level only. .valuein script, not in templates — the template context auto-unwraps signals on read.vueis a peer dependency (types only). Every.valuebox —ref,signal/shallowRef,computed,readonly, andtoRef— borrows Vue's brandedRefin its return type so Volar unwraps it in templates (@click="count++"type-checks). Nothing fromvueis imported at runtime — it's animport type, erased at build. Withoutvueinstalled, template unwrapping falls back to{ value }andcount++reports TS2356.
Styles
- No
scoped, no CSS modules, nolangpreprocessors.<style>is plain global CSS (minified at build).
Reactivity gotchas
:styledoesn't diff stale keys — dropping a key from an object binding between renders doesn't clear the previously-set property.<select multiple>isn't supported byv-model— single-select only.