Getting Started
Five minutes to your first rendered Noma document.
Install
Install the CLI when you want to author documents outside this checkout:
npm install -g @ferax564/noma-cli
noma --version
noma init my-spec
noma render my-spec/demo.noma --to html --out my-spec/demo.html
Install the VS Code extension for syntax highlighting, folding, embedded YAML / JSON / LaTeX / Mermaid / DOT scopes, and warning scopes for raw escape hatches:
ext install ferax564.noma-language
For contributor work, clone the repo and install dependencies:
git clone https://github.com/ferax564/noma.git
cd noma
npm install
Render an example
The repo ships working examples in examples/ — three full-surface demos, starter templates, the original intro files, and a multi-file book:
npm run noma -- render examples/agent-plan.noma --to html --out dist/agent-plan.html
npm run noma -- render examples/research-thesis.noma --to html --out dist/research-thesis.html
npm run noma -- render examples/tech-doc.noma --to html --out dist/tech-doc.html
Open any of the produced files in a browser — they are fully self-contained and include the default theme inline.
Choose a starter template
Copy a template when you want a known-good document shape before adding project-specific content:
cp examples/templates/research-memo.noma my-research-memo.noma
cp examples/templates/decision-record.noma my-decision.noma
cp examples/templates/technical-spec.noma my-spec.noma
cp examples/templates/agent-refresh.noma my-refresh-pack.noma
The rendered template guide explains when to use each one: templates.noma.
Render to LLM context
npm run noma -- render examples/thesis.noma --to llm
npm run noma -- render examples/thesis.noma --to llm --select claim,evidence,risk
npm run noma -- render examples/thesis.noma --to llm --exclude dataset,plot --budget 12000
The output is deterministic plain text designed for LLM input: typed blocks become [CLAIM], [EVIDENCE], [RISK] tags with attributes preserved. --select and --exclude match AST node types or directive names; --budget trims at a line boundary when possible.
List IDs for agents
npm run noma -- ids examples/thesis.noma
npm run noma -- ids examples/book/book.noma.yml
The registry includes canonical IDs in document order, alias-to-canonical mappings, source line numbers, and basic block metadata. On book manifests it uses the same scoped IDs and aliases as validation and rendering.
Use Noma from agents
The CLI is the stable contract, but two public packages make agent integrations easier:
npm install @ferax564/noma-mcp-server
npm install @ferax564/noma-agent-sdk
Use the MCP server from any stdio-capable MCP host:
{
"mcpServers": {
"noma": {
"command": "npx",
"args": ["-y", "@ferax564/noma-mcp-server"]
}
}
}
Use the TypeScript SDK when you want a small client wrapper and retry-aware patch workflow:
import { NomaTools, NomaWorkflow } from "@ferax564/noma-agent-sdk";
const tools = await NomaTools.spawn();
try {
const workflow = new NomaWorkflow(tools);
const result = await workflow.safePatch("memo.noma", {
op: "update_attribute",
id: "launch-decision",
key: "status",
value: "accepted",
});
if (!result.ok) throw new Error(result.error);
} finally {
await tools.close();
}
The server exposes read_doc, list_ids, validate_doc, and patch_block. The SDK remains experimental during v0.x; the patch schemas and CLI behavior are the stable surface.
Validate
npm run noma -- check examples/thesis.noma
npm run noma -- check examples/research-thesis.noma --stale-days 30
The validator catches duplicate IDs, broken references (including [[wikilink]] targets across all chapters of a book), plots missing data, plots referencing unknown datasets or unknown columns, figures without alt text, claims missing evidence, risks without owners, decisions without status, agent tasks without scope, state_change blocks missing block/from/to, citations older than the staleness window, untrusted ::html / ::svg / ::script escape hatches, and (when a profile is declared in frontmatter) any directive outside the declared profile. Add the noverify flag attribute to any block to silence rules on it individually.
The staleness window defaults to 365 days. Override it for one document via stale_citation_days: 30 in frontmatter, for one citation via stale_after_days=30 on the citation, or globally with --stale-days 30 on the CLI.
Pick a theme
npm run noma -- render examples/research-thesis.noma --to html --theme dark
Two themes ship with the CLI: default (warm cream paper) and dark. Inside a document, use {variant="important|subtle|success|danger|info"} on a card, callout, or claim/evidence/risk block to switch its emphasis without touching CSS.
Render a multi-file book
Multi-file projects use a YAML manifest with a .yml / .yaml extension. The CLI auto-detects it:
npm run noma -- render examples/book/book.noma.yml --to html --out dist/book.html
npm run noma -- render examples/book/book.noma.yml --to llm
Chapter paths inside the manifest resolve relative to its directory.
Patch a block (without rewriting the file)
npm run noma -- patch examples/thesis.noma \
--op '{"op":"update_attribute","id":"asml-euv-moat","key":"confidence","value":0.95}' \
--inplace
Seven ops cover the common editing flows: replace_block, replace_body, update_heading, add_block, delete_block, update_attribute, rename_id. The source-preserving patch path rewrites only addressed line ranges or inserted blocks, so unrelated bytes stay byte-identical. See agent-protocol.noma and compatibility.noma for the schema and compatibility policy.
For multi-op agent edits, use a transaction-shaped --ops file:
{
"ops": [
{ "op": "update_attribute", "id": "asml-euv-moat", "key": "confidence", "value": 0.95 }
],
"prevalidate": true,
"postvalidate": true
}
npm run noma -- patch examples/thesis.noma --ops patch.json --inplace
The CLI writes only after every operation applies to an in-memory candidate. If postvalidate finds errors, the original file is left unchanged.
Print the bundled machine-readable schemas when an agent or CI integration needs to validate payloads before calling the CLI:
npm run noma -- schema patch-op
npm run noma -- schema ast
Render with strict HTML safety
npm run noma -- render examples/tech-doc.noma --to html --strict --out dist/tech-doc-strict.html
--strict blocks raw ::html, ::svg, and browser ::script escape hatches and omits external CDN runtimes for math, diagrams, and Plotly. Use it for review or publishing contexts where the artifact must not execute untrusted markup.
Render in GitHub Actions
Add this workflow to another repository to validate, render, and upload a Noma artifact on every push and pull request:
name: Render Noma docs
on: [push, pull_request]
jobs:
noma:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ferax564/noma@v0.11.0
with:
input: docs/spec.noma
output: dist/spec.html
to: html
strict: true
artifact-name: spec-preview
The action installs the CLI from the checked-out action ref by default, runs noma check, renders the requested target, and uploads the output with actions/upload-artifact. For book manifests, set to: site and point output at a directory. If you need an explicit package source, set cli-package to any npm package spec or cli-version to an @ferax564/noma-cli npm version range.
Re-align tables in source
npm run noma -- fmt examples/research-thesis.noma --inplace
GitHub-style pipe tables get rebuilt to a single column width. Tables inside fenced code blocks are skipped. Pipes inside ` code spans and \| escapes are preserved. Idempotent — running fmt` twice produces the same output.
Connect a plot to a dataset
Stop authoring numbers twice — link a plot to a sibling dataset by id:
::dataset{id="vertical-arr"}
schema:
vertical: string
growth: number
rows:
- [legal, 3.4]
- [healthcare, 2.9]
::
::plot{id="arr" type="bar" dataset="vertical-arr" column="growth" xcolumn="vertical"}
::
column= selects the y-series. xcolumn= (optional) pulls categorical labels from a string column. The validator emits errors when the dataset id or column name don't resolve.
Declare a profile
Tell downstream tools which directives the document guarantees to use:
---
profile: research
---
Three built-in profiles ship: minimal (markdown-equivalent), technical (product docs, landing pages), and research (theses, ADRs, recap docs). The validator warns on any out-of-profile directive. Omit the field to keep the open surface.
Render to PDF
The PDF pipeline shells out to Chromium via Puppeteer:
npm run demo
This renders all examples to HTML and produces dist/thesis.pdf. On first run, Puppeteer downloads a Chromium build (~150 MB).
Write your own
Create mydoc.noma:
---
title: My First Noma Document
---
# Hello, Noma
::callout{tone="tip"}
Plain text in. Structured documents out.
::
::claim{id="my-first-claim" confidence=0.7}
Documents that know their own structure are more useful than documents that don't.
::
Then render:
npm run noma -- render mydoc.noma --to html --out dist/mydoc.html
Where to next
- Read docs/spec.noma for the full format specification.
- Read PLAN.md for the long-term vision.
- Read
CLAUDE.mdif you are an agent contributing to this repo.
Next guides
- Case studies for end-to-end workflow narratives.
- Comparison guide for when to choose Noma over Markdown, MDX, raw HTML, or collaborative docs.
- Agent editing guide for safe patch operations and validation.
- Starter templates for copyable document shapes.