ArcMoon 1.1.0

Start

Language

Reference

Nothing matches “”.

↑↓ move Enter open Esc close

Language

Syntax

The whole language on one page: blocks, props, code, loops, components and styles.

This page shows all of ArcMoon in short examples. Each part links to its own page for the details.

Blocks

A block is an HTML element: [name] opens it, [end] closes it, and ! means it has no body.

[section]
  [h1]Users[end:h1]
  [p]Three [strong]active[end] users.[end]
  [hr!]
[end:section]
HTML ArcMoon builds
<section>
  <h1>Users</h1>
  <p>Three <strong>active</strong> users.</p>
  <hr>
</section>

More in Blocks and Self-closing blocks.

Props

Props go after = as name: value. On an element they become attributes:

[a = href: "/users", class: "link"]All users[end]
[input = type: "email", required: true, disabled: false !]
[p = css.color: "teal", --gap: "8px"]Styled[end]
HTML ArcMoon builds
<a href="/users" class="link">All users</a>
<input type="email" required>
<p style="color: teal; --gap: 8px">Styled</p>

More in Props.

Comments

# one line
###
  many lines
###
[p]Shown[end]
HTML ArcMoon builds
<p>Shown</p>

More in Comments.

Escaping and raw text

A backslash makes [, # and ${ plain text. arcm-raw: true writes a whole body as it is:

[p]Write \[p] for a paragraph, \#1 for a number.[end]
[pre = arcm-raw: true][b] and # stay as written[end]
HTML ArcMoon builds
<p>Write [p] for a paragraph, #1 for a number.</p>
<pre>[b] and # stay as written</pre>

More in Escaping and Raw text.

Build-time code

${ }$ runs in Node.js while the page is built. Only its result goes into the HTML:

${ const types = ["string", "number", "boolean"]; }$
[p]ArcMoon props can be ${ types.join(", ") }$.[end]
HTML ArcMoon builds
<p>ArcMoon props can be string, number, boolean.</p>

More in Build-time code.

Loops

[for-each] writes its body once for each item; i is the position:

${ const users = [{ name: "Adam", role: "admin" }, { name: "Eid", role: "editor" }]; }$
[ul]
  [for-each = ${ users }$, as: "user"]
    [li = data-role: ${ user.role }$]${ i + 1 }$. ${ user.name }$[end]
  [end]
[end]
HTML ArcMoon builds
<ul>
  <li data-role="admin">1. Adam</li>
  <li data-role="editor">2. Eid</li>
</ul>

More in Loops.

Runtime code

runtime ${ }$ runs in the visitor's browser. With a signal, the page updates by itself:

runtime ${
  import { signal } from "arcmoon/reactive";
  const count = signal(0);
}$
[button = onclick: runtime ${ () => count(count() + 1) }$]Clicked runtime ${ count() }$ times[end]

More in Runtime code and Reactivity.

Components

A component is another .arcm file. [import] names it, ArcMoon.props() reads its props, and [slot!] holds the body it is given:

UserCard.arcm
${ const { name, role = "member" } = ArcMoon.props(); }$
[article = class: "user"]
  [h3]${ name }$ [small]${ role }$[end][end]
  [slot!]
[end]
[style]
  .user { padding: 8px 12px; border: 1px solid #ddd; }
[end]
index.arcm
[import = UserCard: "./UserCard.arcm" !]
[UserCard = name: "Adam", role: "admin"]
  [p]Joined in 2026.[end]
[end:UserCard]
HTML ArcMoon builds
<style>.user[data-a-ctppmt]{padding:8px 12px;border:1px solid #ddd}</style><article class="user" data-a-ctppmt>
  <h3 data-a-ctppmt>Adam <small data-a-ctppmt>admin</small></h3>
  
  <p>Joined in 2026.</p>

</article>

More in Components and Built-in blocks.

Styles

A [style] is CSS: global in a page, scoped to the component in a component (like UserCard above). css. and -- props style one element. More in Styles.

Lines with no output

A line that only holds things with no output is left out of the HTML entirely, with its indent and line break, so imports, comments and setup code leave no blank lines:

index.arcm
[import = Card: "./Card.arcm" !]
# a comment
${ const n = 2; }$
[main]
  [p]${ n }$[end]

  [p]a blank line above stays[end]
[end]
HTML ArcMoon builds
<main>
  <p>2</p>

  <p>a blank line above stays</p>
</main>
  • Things with no output: [import], comments, a top-level runtime ${ }$ block, and a ${ }$ that doesn't end with a value (like ${ const n = 2; }$).
  • Blank lines you write between elements are kept.