Marque is a static site generator powered by .mq: markdown plus layout directives.
You write content quickly, keep structure explicit, and ship plain static HTML/CSS.
Architecture and module roles are documented in ARCHITECTURE.md.
Directive extension workflow is documented in DIRECTIVES_DEV.md.
Theme authoring workflow and the copy-paste LLM prompt live in THEMING.md.
- Markdown-first authoring with composable layout blocks.
- Zero runtime framework on the generated site.
- Built-in live reload for fast docs and content workflows.
- Theme system with CSS-only themes and a shared layout shell.
- Per-page controls via frontmatter (
theme,width,align, nav metadata, etc.).
Requirements: Node.js 18+
npm install
npm linkAfter linking, the marque command is available globally.
marque new D:\Sites\my-site
cd D:\Sites\my-site
marque serve .Choose a starter layout/theme at scaffold time:
marque new D:\Sites\docs-site layout:sidebar theme:goudaOpen http://localhost:3000.
When ready to publish:
marque build .Output goes to dist/.
marque new <dir> [layout:<name>] [theme:<name>] scaffold a new site
marque serve <dir> dev server with live reload (default port 3000)
marque build <dir> compile site to dist/
marque migrate <src> [target] [--from mdbook|mkdocs] import a supported docs site
marque theme new [site-dir] <name> create a token-first theme
marque theme template [site-dir] [out-file] advanced theme scaffold
<dir> defaults to ..
Marque can import the docs generators that are structurally closest to it first:
mdBookMkDocs
Examples:
marque migrate ./old-book
marque migrate ./old-book ./new-marque --from mdbook
marque migrate ./old-docs ./new-marque --from mkdocs --layout sidebar --theme comteThe migration command creates a fresh Marque site, copies markdown pages into pages/, copies non-markdown docs assets into static/, generates summary.mq, and adds a migration-notes.mq page for anything that still needs manual review.
my-site/
├── directives/ # custom or overridden directive definitions
├── pages/ # .mq source pages
├── layouts/ # shared shell + layout CSS copied at scaffold
├── themes/ # custom/current themes at root; legacy built-ins in legacy/
├── static/ # copied as-is to dist/
├── marque.toml # site config
└── dist/ # generated output
Built-in starter layouts, themes, and directive files are sourced from template/ in the package, then copied into each new project.
marque.toml controls global defaults:
title = My Site
description = Built with Marque
repo = https://github.com/you/my-site
layout = topnav
theme = comte
width = 82
align = center
summary = falsetitle: site title used in templates.description: fallback page meta description.repo: optional repository URL shown in the shared footer.layout: global layout name (topnavorsidebar). legacy valuesdefault,xmb, andcrossmediabarresolve totopnav.theme: global theme name.width: global page width occupancy (percentage-based, see below).align: default content column alignment (left,center,right).summary: default page summary rail setting for the whole site. Pages can still override it in frontmatter.
Each page can override defaults with TOML frontmatter:
+++
title = Syntax Reference
nav = syntax-reference
theme = rustique
layout = sidebar
width = 90
align = left
summary = true
+++title: page title.nav: output slug / route filename.theme: optional per-page theme override.layout: optional per-page layout override.width: optional per-page width override.align: optional per-page content column alignment (left,center,right).summary: optional per-page boolean that overrides the site default for the page summary rail.
Marque uses summary.mq (mdBook-style) to define navigation labels and ordering.
Example:
# Summary
[Home](index.mq)
[Quickstart](quickstart.mq)
[Docs](docs.mq)
[Cheat Sheet](cheat-sheet.mq)Notes:
- Frontmatter
orderis no longer used. - Link text in
summary.mqbecomes nav label. - Link target controls nav order and page sequence.
Width supports:
- Named presets:
narrow,normal,wide,full. - Percent numeric:
86->86%. - Explicit percent:
86%.
Fallback order for width:
- Page frontmatter
width marque.tomlwidth- Theme default max width
Marque parses custom directives in addition to markdown.
@tag .modifier optional-name
content
@end tag optional-name
Core directives:
@container@row/@card@callout@stat@hero/@section@divider(self-closing)
Example:
@row intro
@card .accent one
## Fast
Build rich docs with markdown and layout blocks.
@end card one
@card two
## Simple
Output is plain static HTML and CSS.
@end card two
@end row intro
Custom directives live in directives/*.js inside your site.
Each file exports a registration function that receives { defineDirective }.
module.exports = ({ defineDirective }) => {
defineDirective('product-card', {
type: 'block',
render: ({ mods, name, children, ctx }) => {
const variant = ctx.escapeAttr(mods[0] || 'default');
const title = ctx.escapeAttr(name || '');
return `<product-card variant="${variant}" title="${title}">${children}</product-card>`;
},
});
};- Button classes:
[Download](/file.zip){.primary} - Auto button detection for links like
Read ... → - Badges:
@badge "Stable" {.ok}
Themes live in themes/ and use flat files:
<name>.css(required)
Bundled showcase and backwards-compatible built-ins now live in themes/legacy/:
legacy/<name>.css
Layouts own the shared page shell and layout behavior:
index.html(shared HTML shell)index.js(shared runtime helpers)<name>.css(layout-specific structure and responsive framing)
common.css owns the shared component baseline. Themes should stay token-first and only add a few intentional overrides. Use legacy/<name> when you specifically want an older bundled theme variant.
Create a new theme with:
marque theme new my-themeFor the full theme workflow, ownership rules, and an LLM-ready prompt, see THEMING.md.
Themes are plain CSS files. Recommended pattern:
:root {
--mq-primary: #c85a2a;
--mq-secondary: #2a5ac8;
--mq-tertiary: #2ac852;
--mq-background: #f7f5f0;
--mq-surface: #ffffff;
--mq-surface-alt: #eeece7;
--mq-text: #1a1916;
--mq-muted: #6b6860;
--mq-border: rgba(0,0,0,0.09);
--mq-radius: 8px;
--mq-max-width: 860px;
}Editable variables used by built-in styles:
--mq-primary--mq-secondary--mq-tertiary--mq-background--mq-surface--mq-surface-alt--mq-text--mq-muted--mq-border--mq-radius--mq-max-width--mq-font-sans--mq-font-serif--mq-font-mono
--mq-nav-bg--mq-nav-text--mq-nav-border--mq-nav-active-bg--mq-nav-active-text
--mq-code-bg--mq-code-text--mq-code-border--mq-code-head-bg--mq-code-head-text
--mq-card-bg--mq-card-border--mq-card-radius--mq-card-shadow
--mq-callout-info-bg--mq-callout-info-border--mq-callout-info-text--mq-callout-warn-bg--mq-callout-warn-border--mq-callout-warn-text--mq-callout-danger-bg--mq-callout-danger-border--mq-callout-danger-text--mq-callout-ok-bg--mq-callout-ok-border--mq-callout-ok-text
:root {
--mq-primary: #c85a2a;
--mq-secondary: #2a5ac8;
--mq-tertiary: #2ac852;
--mq-background: #f7f5f0;
--mq-surface: #ffffff;
--mq-text: #1a1916;
--mq-border: rgba(0,0,0,0.09);
--mq-nav-bg: #111827;
--mq-code-bg: #0b1220;
--mq-card-shadow: 0 10px 30px rgba(2, 6, 23, 0.08);
}Template resolution order:
layouts/<layout>.htmllayouts/index.html- legacy
themes/index.html - packaged fallbacks in
template/layouts/andtemplate/themes/
Layout resolution order:
site/layouts/<layout>.cssmarque-pkg/layouts/<layout>.css
Current built-in themes in this repo include:
comte(default)goudapycorinorustique
Legacy/showcase themes live under themes/legacy/:
legacy/defaultlegacy/destinylegacy/elmentallegacy/gruyerelegacy/javartilegacy/midalegacy/pycorinolegacy/rustique
marque theme new my-themeFor an advanced scaffold that includes selector placeholders based on directive output:
marque theme template . themes/my-theme.css --reference comteOptional custom shell:
cp /path/to/marque-pkg/template/layouts/index.html layouts/index.htmlThen set:
theme = my-thememarque servewatchespages/,static/,themes/,layouts/,directives/, andmarque.toml.- Any change triggers rebuild + browser reload.
static/is copied directly intodist/.
ISC