Reference
Configuration
Every arcmoon.config.js key and every JavaScript API option: defaults, examples, when to use them.
Two ways to set options
- The CLI (
arcm build) readsarcmoon.config.jsfrom the folder you run it in. - The JavaScript API (
new ArcMoon(options)) takes the same names in its options object, plus a few of its own. It doesn't read the config file.
Every option is optional: leave one out, and its default is used.
arcmoon.config.js
arcm init creates the config in the current folder. Every option, with its default:
export default {
importAliases: { "@": "./src" }, // short names for folders in [import] paths
removeComments: true, // leave # comments out of the HTML
timeout: 5000, // ms each page's ${ }$ code may run
bundle: [], // npm packages allowed in runtime code
packages: {}, // runtime imports loaded from a URL: { dayjs: "https://…" }
outDir: "./dist", // where arcm build writes
externalScripts: false, // true: JavaScript in files, not inside the HTML
externalStyles: false, // true: CSS in files, not inside the HTML
assetsDir: "assets", // folder inside outDir for JS, CSS and url() files
base: undefined // e.g. "/": file URLs from the site root
};ArcMoon reads it only from the folder you run arcm in, never from a parent folder. Run arcm from your project folder. arcm show config prints what it found.
The options
Every option is optional: leave one out, and its default is used.
importAliases
Short names for folders, used at the start of [import] paths. Default: none.
export default {
importAliases: { "@": "./src", "~ui": "./src/components" }
};# in any file, however deep
[import = Card: "@/components/Card.arcm" !] # → ./src/components/Card.arcm
[import = Badge: "~ui/Badge.arcm" !] # → ./src/components/Badge.arcmTargets start from the project folder. Without the alias, a page in pages/blog/ would need ../../src/components/Card.arcm. More in Import aliases.
removeComments
Whether # and ### comments are left out of the HTML. Default: true.
export default { removeComments: false };# Page header
[h1]Home[end]<!-- Page header-->
<h1>Home</h1>With the default, the HTML is just <h1>Home</h1>. Keep comments when they should ship with the page, like a license note. More in Comments.
timeout
How many milliseconds each page's ${ }$ code may run, its components included. Default: 5000 (5 seconds).
export default { timeout: 10000 }; // 10 seconds, for pages that fetch a slow APICode that takes longer is stopped: endless loops, timers and pending requests all end, and the build stops with:
✗ ${ }$ code took longer than 10000 ms and was stopped
pages/stats.arcmRaise it only if a page really needs the time. A page that hangs usually has a bug, and the timeout is what stops it.
bundle
The npm packages runtime code may import. Default: none. Runtime code goes to every visitor, so ArcMoon only bundles packages you list:
export default { bundle: ["canvas-confetti", "dayjs"] };runtime ${ import confetti from "canvas-confetti"; }$
[button = onclick: runtime ${ () => confetti() }$]Party[end]Install the package first (npm install canvas-confetti). Without the entry, the build stops:
✗ runtime import "canvas-confetti" is not listed in bundle (arcmoon.config.js). Add it to bundle to bundle it from node_modules, or to packages to load it from a URLNot needed for arcmoon/reactive, your own .js files, URL imports, packages used only in ${ }$ (they never reach the browser), or CSS @imports.
packages
npm names that runtime code loads from a URL instead of bundling them (ArcMoon 1.1). Nothing is installed or downloaded at build time; the visitor's browser loads the URL:
export default {
packages: { dayjs: "https://esm.sh/dayjs@1" }
};import dayjs from "dayjs"loadshttps://esm.sh/dayjs@1;"dayjs/plugin/utc"loads that URL +/plugin/utc.- A key can also be a full path, like
"lit/html.js". Values must start withhttps://. - It is the same option the browser build takes.
outDir
The folder arcm build writes into. Default: "./dist".
export default { outDir: "./public" };arcm build pages/about.arcm
✓ pages/about.arcm → public/about.html 14 B-o on the command line wins over it: arcm build pages/blog -o public/blog.
externalScripts
Where each page's JavaScript goes. Default: false, inside the HTML in a <script>.
export default { externalScripts: true };index.html <script type="module" src="./assets/index-MTLSBKEV.js">
assets/
index-MTLSBKEV.js this page's code
chunks/
chunk-E7XXX4QS.js code shared by pages, like arcmoon/reactive- Inside (default): one file per page, nothing else to copy. Good for small sites and single pages.
- In files: shared code is downloaded once and cached across pages. Good for sites with many pages.
externalStyles
Where each page's CSS goes. Default: false, inside the HTML in a <style>.
export default { externalStyles: true };index.html <link rel="stylesheet" href="./assets/index-IH2BDP4O.css">
assets/
index-IH2BDP4O.css all of this page's CSSIt is separate from externalScripts: you can have the JavaScript in files and the CSS inside the page, or the other way round.
assetsDir
The folder inside outDir for JavaScript and CSS files, and for url() files copied from CSS. Default: "assets".
export default { externalScripts: true, assetsDir: "static" };index.html <script type="module" src="./static/index-QZCVOMHP.js">
static/
index-QZCVOMHP.jsbase
How pages link to those files. Default: relative to each page (./assets/…). Set it to the URL where outDir is served:
export default { externalScripts: true, base: "/" };<!-- default -->
<script type="module" src="./assets/index-MTLSBKEV.js"></script>
<!-- base: "/" -->
<script type="module" src="/assets/index-MTLSBKEV.js"></script>- Use it when pages are served from paths that don't match their files, for example by a server that rewrites URLs.
- Subfolders built with
-oget their ownassets/(dist/blog/assets/). When the-ofolder is insideoutDir,basegets that folder:-o dist/blogwithbase: "/"links to/blog/assets/…(ArcMoon 1.1).
Options only in the JavaScript API
These go in new ArcMoon({ … }) next to the options above. See the JavaScript API for compile() and build().
filename and src
The page to build: a file, or the page as a string. Give one of them.
new ArcMoon({ filename: "pages/index.arcm" });
new ArcMoon({ src: "[p]Hello ${ 2 + 3 }$[end]" });With both, src is the code and filename is its name in messages and the folder its imports start from. With src alone, the page is called anonymous.arcm, in cwd.
props
Data for the page, read with ArcMoon.props() like a component's props. Default: none.
const html = await new ArcMoon({
filename: "pages/user.arcm",
props: { name: "Maryan" }
}).compile();${ const { name } = ArcMoon.props(); }$
[h1]Hello, ${ name }$[end]Props are copied in as real values (objects, arrays, dates), never turned into text. Use them for one template and many pages, or a server that builds a page per request.
cwd
The project folder: where relative paths start. Default: process.cwd(), the folder Node.js runs in.
- A relative
filename, andimportAliasestargets, start here. - A
[script = src: "/app.js"]that starts with/is read from here. - Packages in
bundleare found in itsnode_modules.
new ArcMoon({ filename: "pages/index.arcm", cwd: "/home/adam/my-site" });root
The folder whose files count as yours for the protector. Files outside it are templates, which must be trusted before their code runs. Default: cwd.
// a build script in tools/, for the project one folder up
new ArcMoon({ filename: "pages/index.arcm", cwd: "..", root: ".." });dev
true: the page's JavaScript isn't minified and has a source map back to the .arcm lines, so browser errors show real names and lines. Default: false. The CLI's arcm build --dev sets it.
# with dev: true, a browser error points at the .arcm file
TypeError: Cannot read properties of undefined (reading 'value') pages/index.arcm:5:22onWarning
What to do with each warning. It gets { source, position, message }: the file, { line, character } counted from 0 (or null), and the text. Default: print one line, ⚠ page.arcm:3:7 ….
// fail a CI build on any warning
const warnings = [];
await new ArcMoon({ filename: "pages/index.arcm", onWarning: (w) => warnings.push(w) }).compile();
if (warnings.length) process.exitCode = 1;Read the three fields; don't parse the text, which can change in any release.
name
The page's name in build() and buildPages(): its entry in pages, and the start of its file names (post-MTLSBKEV.js). Default: the file name without .arcm, or page for src.
const pages = posts.map((post) => ({
filename: "templates/Post.arcm",
name: post.slug, // its name in pages[], and the start of its file names
props: { post }
}));Options of build() and buildPages()
These say where files go and how pages link to them. They match the config keys of the same name, with one difference: externalScripts is true by default here, so JavaScript goes into files. The CLI and compile() put it inside the page.
- outDir, assetsDir, base, externalScripts (default
true), externalStyles: forbuild()andbuildPages(). - bundle, packages, cwd, dev, onWarning: in
buildPages()'s second argument, for all pages at once.
// one page
const { html, files } = await new ArcMoon({ filename: "pages/index.arcm" }).build({
outDir: "dist",
base: "/"
});
// many pages: page options first, then options for all of them
const { pages } = await buildPages(
[{ filename: "pages/a.arcm" }, { filename: "pages/b.arcm" }],
{ outDir: "dist", bundle: ["dayjs"] }
);siteDir
buildPages() only (ArcMoon 1.1). The site's main output folder, when outDir is a folder inside it: base then gets that folder. Default: outDir. The CLI passes your config's outDir, so -o builds link right.
await buildPages(posts, { outDir: "dist/blog", siteDir: "dist", base: "/" });
// pages link to /blog/assets/…In the browser
The browser build has options of its own (files, baseUrl, packages, env…): see Browser build.