A minimal static-site layout engine.
colvmn (pronounced column — the v is Latin-styled for u) is a tiny layout engine for static sites. Pages are described by an _index.md with YAML frontmatter, or an _index.json. The engine renders each page to static HTML at build time and to live DOM in the browser, so content is visible to JavaScript-free crawlers and to readers with JavaScript enabled.
This page is itself generated by colvmn — the engine is self-hosting, with no recursive submodule.
Add colvmn to your site as a submodule:
git submodule add https://github.com/stevedekorte/colvmn.git colvmnMake each page a directory with two files. index.html is a thin shell:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/colvmn/style.css">
<title>My Page</title>
</head>
<body>
<div class="page"></div>
<script src="/colvmn/layout/layout.js" type="module"></script>
</body>
</html>_index.md holds the content:
---
title: My Page
topTitle: My Site
subtitle: A short tagline for the page.
---
## Overview
Regular markdown — headings, paragraphs, lists, tables, fenced code.Regenerate static HTML, sitemap.xml, llms.txt, and llms-full.txt from the site root:
node colvmn/static-gen.jsPages can mix markdown with structured blocks via _index.json or the content array in frontmatter:
| Block | Purpose |
|---|---|
ContentText | Headings, paragraphs, prose sections |
ContentCards | Grid of linked cards, auto-populated from subfolders |
ContentTable | Tables with headers, rows, and an optional caption |
ContentTimeline | Dated entries in chronological order |
ContentImage | Figures with alt text and captions |
ContentKeyValue | Two-column key/value pairs |
ContentUnorderedList | Bulleted lists |
ContentOrderedList | Numbered lists |
ContentFAQ | Collapsible question/answer entries |
ContentToc | Auto-generated table of contents |
New block types drop in by extending ContentBase and registering in layout.js and static-gen.js.
At build time, static-gen.js walks the site tree, finds every directory that has both index.html and an _index.md (or _index.json), runs the layout engine against each one, and writes the rendered HTML back into index.html. At runtime, layout.js does the same thing in the browser, replacing the pre-rendered content with a freshly rendered copy. The two paths produce identical output.
The generator also writes:
sitemap.xml — every page URLllms.txt — a curated index for LLM agentsllms-full.txt — the full site content as markdown, one page per sectionWhen the optional llms-config.json at the site root sets siteUrl, canonical tags and absolute sitemap entries are emitted.
colvmn renders its own pages without being a submodule of itself. Pass the site root explicitly:
node static-gen.js .The root index.html references ./style.css and ./layout/layout.js directly instead of /colvmn/....
Source: github.com/stevedekorte/colvmn
License: MIT.