FrontierJS

Mesa guide / Reference

@frontierjs/mesa — compiler

The compiler turns .mesa and .md source into an ES module. It is exported from @frontierjs/mesa and from @frontierjs/mesa/compiler (the same file). Markdown has its own entry, @frontierjs/mesa/compiler-md.

import { compile, compileSource, compileFile } from '@frontierjs/mesa'

Every function is async and answers one object, ctx. A build reads ctx.result and decides what to do about ctx.analysis.errors. See Errors and warnings.

compile

compile(source: string, options?: object): Promise<ctx>

Compiles a .mesa source string. It never routes to Markdown, whatever the filename says.

compileSource

compileSource(source: string, options?: object): Promise<ctx>

Compiles by file extension: a filename ending in .md goes to compileMd, anything else to compile. The extension decides the language. A --- block at the top of a .mesa file is metadata (a route's title, its render mode): it is stripped, returned as ctx.frontmatter, and does not turn the file into Markdown. options.path works as an alias for filename.

compileFile

compileFile(filepath: string, options?: object): Promise<ctx>

Reads the file, then calls compileSource with filename set to the path.

compileMd

import { compileMd } from '@frontierjs/mesa/compiler-md'

compileMd(source: string, options?: object): Promise<ctx>

Compiles Markdown with frontmatter. Frontmatter keys become export const declarations, and {expressions}, blocks and components work in the prose. It needs the unified packages installed in your app; without them the import fails with an error that names the install line. See Markdown files.

Options

OptionDefaultEffect
filename''Names the file in error messages, dev labels and source positions, and picks the language in compileSource
devfalseEmit the registration calls DevTools and HMR read, and turn loc on
debugtruefalse strips every $.inspect call from the output
csstruetrue emits the scoped styles into ctx.result as an addStyles call. false emits nothing and hands them back on ctx.css.result
locthe value of devStamp each template element with data-fjs-loc="File.mesa:line:column", which click-to-source reads
preserveCommentsfalseKeep HTML comments in the template
compacttrueCollapse whitespace in the template. 'full' collapses it inside text nodes too. It is never collapsed in <pre> or <textarea>
warningconsole.warnCalled with { message } for every error and warning the compile collects
externalReactivityHints'default''strict' also warns about every read off an imported object that no $: watch covers
externalSignalsnoneMaps a module path to the names it exports that are signals, so reads of them are reactive
remarkPlugins[].md only. Plugins for the Markdown stage, each a function or a [plugin, options] pair
rehypePlugins[].md only. The same, for the HTML stage

With css: false every element still carries the scope class, so a page whose caller forgets to inject ctx.css.result looks right in the markup and matches no rule.

The result

FieldHolds
ctx.resultThe compiled JavaScript module, as a string
ctx.analysis.errorsStrings. Anything in here means the output must not ship
ctx.analysis.warningsStrings. The build succeeds and the code is probably wrong
ctx.css.resultThe scoped CSS. Filled only when css: false
ctx.css.idThe content-addressed scope class on every element. Two components with identical CSS share an id
ctx.frontmatterThe parsed frontmatter object, for .md and .mesa. undefined when the file has none
ctx.layout.md only: the frontmatter layout value, or null
ctx.isStatictrue when the component needs no JavaScript at runtime
ctx.islandsEach client:* call site, for a loader that maps a component name to a module

Errors and parse failures

The compiler reports and the build decides. A broken construct is pushed onto ctx.analysis.errors and compile still answers, so a caller that ignores the list will ship broken output. A source that cannot be parsed at all (an unclosed element, a $: where it does not belong, a banned spelling such as on:click) throws instead, with the position in the message.

const ctx = await compileSource(source, { filename: 'Counter.mesa' })
if (ctx.analysis.errors.length) throw new Error(ctx.analysis.errors.join('\n'))

The Vite plugin does this for you. See Vite, HMR and DevTools.


Spec: VISION.md § 18.7 · RULE 53