Mizzen

Programmatic API

2 minutes read

The package exposes two entry points today:

Entry Exports
@velella/mizzen version.
@velella/mizzen/contracts The frozen contract types, type-only.

test/contracts-import.test.ts builds the package and imports each entry point the way a consumer does, so the table above is checked against the artifact.

Inside the repository, each stage is a function with typed input and output:

Function File Returns
build(options) src/pipeline/build.ts BuildResult: the output folder, every file written (sorted), and every diagnostic.
buildModel(root) src/model/build.ts ModelResult: the complete site model plus diagnostics. It parses, renders Markdown, and builds navigation, but writes nothing.
applyFacts({ site, root, sourceDir, dir? }) src/model/facts.ts ApplyFactsResult: the site with each derived fact's value at data[fact.name], plus diagnostics. buildModel calls it.
loadConfig(root, options?) src/config/load.ts LoadConfigResult: a complete SiteConfig after defaults, plus diagnostics.
loadRegistry(themeRoot) src/render/registry.ts ThemeRegistry: the theme manifest, layouts, chrome, and components.
loadCodeConfig(root, options?) src/plugins/hooks.ts LoadedCode: the site's plugins and diagnostics. See Plugins.

build() takes:

  • root: the site root, the folder that holds mizzen.yml.
  • out: the output folder, replaced as a whole. It must be outside source, or its first segment must start with _ or ., as in _site.
  • themeRoot: the theme's root folder, which holds src/index.ts and the layouts/, chrome/, and components/ folders.
  • themeFiles: theme files to copy, as paths relative to themeRoot; each lands under assets/theme/ with its hash in the name.
  • defaultLayout: the layout for a page that names none; without it such a page is an error.
  • outputsDir: the folder outputs are read from; default src/outputs/.
  • cache: reuse an unchanged build's output from the cache; off by default, and mizzen build turns it on.
  • cacheDir: the cache folder; default <root>/.mizzen/cache, and only used when cache is true.
  • workers: pages to render at once in worker threads; default 1, which renders in this process. 2 or more starts that many workers, each loading the theme.

Every output runs first, in memory, and its files are checked: a path outside out is an error, and so is a path two outputs both write (the first one wins). Then the site is written to a staging folder beside out and swapped in only when complete. A site's own file wins over an output's file at the same path, with no diagnostic. Problems in content and theme come back as diagnostics; a throw means a bug, such as an output or layout that threw, and leaves out as it was.

import { build, type BuildResult } from "../src/pipeline/build.ts";

/** Builds a site and returns what was written. */
export function buildSite(root: string, out: string, themeRoot: string): Promise<BuildResult> {
  return build({ root, out, themeRoot, defaultLayout: "doc" });
}

buildModel() is the API for a tool that reads the site without writing it, such as a linter or an MCP server. Its diagnostics are the same ones a build reports.

View Markdown

Use with an agent
View Markdown

Open in