Getting started
Enrich the Markdown you already have
Markset is not a new format to migrate to. A Markset file is a Markdown file, so the way in is to keep the documents you have and start using constructs in the pages that need them. This page covers when that is worth doing, and the four ways to fit it into something you already run.
When it helps
The problem it solves
You have Markdown that has outgrown Markdown. A page needs three things side by side, or a set of tiles, or a procedure that reads as a procedure. The usual answer is to drop into raw HTML, and the moment you do, the file stops being portable: it will not paste into an issue, it will not typeset to print, and a future renderer has to cope with whatever tags you left behind.
Markset is the other answer. You name the layout instead of building it, and the name has a defined fallback, so the file keeps working everywhere it used to work.
An internal documentation site
The common case, and the one this project was written for. Pages are Markdown in a repository, a generator turns them into a site, and some of them want to be richer than a wall of prose. You keep the repository, the review process and the file format, and the pages that need more get it.
A public site or GitHub Pages
Same shape, published. The site you are reading is the worked example: every page is a Markset document, built by the reference implementation, deployed by a workflow. There is no framework underneath it.
Documents that get pasted around
Analyses, incident write-ups, proposals. These end up in issues, pull requests and chat, where nothing renders your layout. A Markset document degrades to readable Markdown in those places rather than to a soup of angle brackets.
Content that has to outlive its renderer
A closed vocabulary with a specification and a test suite means a second implementation can be written from the document alone. That is a different promise from a template language tied to one generator.
It is not a site generator and not a component framework. Markset gives you a document format and two things that read it: markset html, which produces HTML, and markset downgrade, which produces plain CommonMark with the layout lowered away. Whatever builds your site keeps building your site.
Fitting it in
Four ways to adopt it
-
Author in it and change nothing else
The cheapest option, and a real one. Write constructs in your Markdown and let your existing renderer show the fallback: a grid is a list, a card is a heading and its body, a metrics block is a table. You get a document that is better organized at the source level today, and rich when you decide to render it properly.
The only thing to add is validation, so a typo fails in review rather than shipping:
markset check docs/*.md -
Render to HTML and let your generator embed it
If your site generator takes HTML, this is a preprocessing step. Render each page to a fragment and hand it over, with the stylesheet linked once in your layout.
markset html docs/architecture.md --fragment -o build/architecture.htmlThe fragment carries
ms-class names and nothing else. Link the default stylesheet, or your own, from your existing template. -
Downgrade first, if your generator must stay untouched
If you cannot change the pipeline at all, lower the constructs away before the generator sees them. The output is ordinary CommonMark that anything handles.
markset downgrade docs/architecture.md -o build/architecture.mdYou keep the structured source and lose only the layout, which is the same trade the fallback makes anywhere else.
-
Call it as a library
For a generator you control, skip the process boundary. The parse result is mdast plus a few node types, so anything in the unified ecosystem can walk it.
import { parseDocument } from "@markset/parser"; import { renderHtml } from "@markset/render-html"; const { ast, diagnostics } = parseDocument(source); if (diagnostics.some((d) => d.severity === "error")) throw new Error("invalid document"); const body = renderHtml(ast);
A first page
Enriching a page you already have
Take a page that is already in your repository. This one is fine as it is, and it is the shape most documentation is in:
## Deployment
Three environments, in order.
- Staging, deployed on merge
- Canary, one percent of traffic
- Production, manual promotion
Rollback takes about four minutes.
What it costs you
Nothing yet. The page above is plain CommonMark, which means it is already a valid Markset document. You have not adopted anything.
Now declare the version and turn the list into tiles. Two lines changed:
---
markset: 0
---
## Deployment
Three environments, in order.
:::grid{cols=3}
- **Staging** — deployed on merge
- **Canary** — one percent of traffic
- **Production** — manual promotion
:::
Rollback takes about four minutes.
Staging — deployed on merge
Canary — one percent of traffic
Production — manual promotion
Rendered with markset html. Paste the same source into a pull request and you get the three bullets back, in order, with the fence lines showing as text.
The markset: 0 line declares which version of the specification the document is written against. The parser does not require it; tools use it to decide that a .md file is meant to be Markset, which protects files that use ::: for something else.
Honest constraints
What to know before you commit
| Constraint | What it means |
|---|---|
| GitHub shows the fallback, not the layout | A grid renders as a list in a repository preview. Callouts are the exception: they use GitHub's own alert syntax and render natively. |
| Rich output needs a build step | Something has to run the renderer. That is one command, with no configuration file, but it is not nothing. |
| Themes are yours to write | Eight constructs come styled by the default stylesheet. Author classes beyond the reserved ones mean whatever your stylesheet says, and you write that stylesheet. |
| The vocabulary is closed | There are eight constructs and an unknown name is an error. If you need a ninth, the answer is a class and a theme rule, not a new directive. |
| Nothing executes | No expressions, no includes, no components. A document is data. If you need computation, it happens before the document exists. |
Next
Where to go from here
- Read the reference. It starts with the three pieces of syntax every construct is built from, then gives one page per construct with four worked examples each, and a page on frontmatter and theme tokens for the settings a document carries about itself.
- Skim the CLI page for the four commands and their flags.
- Look at the examples to see what a long document looks like when it has a theme of its own.
- Read the specification when you want the normative answer. It is short, and it is what a second implementation would be written from.