FrontierJS

Mesa guide / Reference

Every rule

The language spec numbers its rules. Each row is a one-line summary and a link to the section of VISION.md that states it in full.

RuleSummarySection
1$: is top-level only. A nested one is a compile error4.8
1bAn instance script runs in source order. A declaration is pulled up only when something already emitted needs it2
2A const that reads reactive variables is derived2.2
3Every reactive variable used in a template is wired automatically2
4Scoped variables are never tracked, but can read and write top-level state2
5All Mesa source and compiler output is valid JavaScript1
6Path watching uses optional-chaining semantics: ?. is soft, none is hard4.1
7In a watch with a handler, the handler is last and outside the parentheses4.2
8Shared state is plain JavaScript. A $: path makes it reactive per component5
9Store files cannot import component files. Not checked by the compiler5
10A circular reactive store import is an error5
11Static paths become targeted accessors. Dynamic paths become runtime effects14
12A template path is an ordinary expression. A nullish value renders empty14
13var reads without subscribing and writes without notifying6
13abind: on a var is a compile error that names oninput3.4
14A let initializer is a snapshot. Use $: name = expr to keep deriving2.1
14aA writable derived override is temporary. A dependency change wins back4.5
14b$: (a, b) is a multi-path watch. $: { } is an auto-tracked block effect4.4
15Components are ES modules, so top-level await is valid13.1
16$async.x exists for a top-level const x = await … and a top-level async function x()13.2
17A non-const reactive variable can be assigned any time. Last write wins13.3
18Builtins are reached through $, with no import17
18a$ cannot be destructured, aliased or shadowed17
18b$ does not exist in <script module>11
18c$props, $attributes, $slots, $context and $async have a canonical bare spelling17
18dFour prefixes: $, $:, $$ and __. The whole $$ prefix and the three __ names are reserved17
18e$class and $dom are protocol names, never authored17
19On a server, signals are synchronous, $.onMount does nothing and $context is per instance19.3
20There is no hydration. An island is a fresh mount() into a marked range19.3
21The compiler targets @frontierjs/mesa/runtime1
22bind: is valid only on export let props3.4
22aOn an element, bind: is value, checked, files, group and this10.1
23One event spelling, onclick={fn}, with modifiers piped on8.2
24bind:group needs a top-level let10.3
25$context provides and consumes are top-level in the script7.1
25aA const consumer tracks the provider. A let initializes at mount. A var snapshots7.4
25b$context.<key> is a compile step, so script-only. context.use and context.provide work anywhere7.4
26client:* is stripped by the compiler. islands: true marks it in a server render18.6
27{#key expr} destroys and recreates its content when expr changes9.4
28{#snippet} defines a template fragment. {@render} mounts it9.5
29Snippets close over outer reactive variables. Arguments are plain values9.5
29bEvery non-void element closes explicitly. HTML's optional end tags are a parse error10
30<script module> runs once at module load, shared by all instances11
31class="…" on a component is forwarded to the child's class prop10.8
31a$class is a protocol name. Use {class} or bind:class on the child element10.8
31bbind:class on an element is a compile error. {class} is the merging form10.8
32bind:class and {class} on an element wire the parent's class through10.8
33{@html expr} injects raw HTML. Use it on trusted content only10.7
34{#virtual each} takes height and viewport. Variable row height is not supported9.7
35Snippet props are export let. <slot /> is the preferred way to receive content9.6
35achildren with {@render children?.(value)} is the form for content the child parameterizes9.6
35b<slot> takes no attribute but name9.6
36bind:this on a component exposes exported props and functions, never a DOM node10.2
37$.mounted(fn) appears once per component12.6
37a$.mounted(fn) is wired by name: const ready = $.mounted(fn)12.6
38<mesa:mounted> gates the whole component template12.6
39onerror on <mesa:mounted> runs on rejection, apart from the failed snippet12.6
40<mesa:boundary> and <mesa:mounted> resolve snippets in one order: local, global, blank12.6
41bind:value|mask needs a pattern argument in { }10.1
42$.inspect is dev-only, stripped when debug is false, and top-level only17
43Replacing a value notifies. Mutating one does not, unless a $: path covers it4.0
44Every let and const in the component is reactive. An import is inert until a $: names it4.0
45A watch fires only for writes through the proxy Mesa made4.1
46A watch covers its path and everything beneath it4.1
47Watches belong to the object, shared across components4.1
48delete obj.key notifies like obj.key = undefined4.1
49Date, Map, Set, RegExp, Promise, typed arrays and Error pass through the proxy untouched4.1
50A $: { } block whose statements are all bare reads is a compile error4.8
51Reactive logic does not belong in .js modules5
52In a $: { } block the handler is an inline function4.2
53The compiler reports and the build decides4.8
54createRoot gives ownership without tracking5
55Scoped CSS applies to the selector's subject. Cross a boundary with :global(...)5
56An instance script exports export let, export const, export var and export function, and nothing else3.5
57<mesa:element this={expr}> takes a non-empty tag name. A new tag rebuilds the element12.5
58An unknown mesa: name is a compile error12.5
59prev holds a reference. A mutated object gives the same reference for both4.2
60Auto-tracked effects run on mount and cannot be deferred4.3
61Everything that builds DOM runs before user effects in a flush4.7
62An auto-tracked effect's first run is during setup, before the template exists4.7
63In a .md file, {…} in prose is a bare path. Anything else is literal text18.4
64A call to an imported function re-runs when the component's import watches fire4.1
65$.after and $.every are top-level declarations. $.sleep works anywhere17
66setTimeout and setInterval in a script are a compile warning17

The numbers are citation keys and are never reused, so 18d can sit before 18c in the spec. Page footers in this guide cite them.


Spec: VISION.md § 22