Loom
Literate programming framework for AI-assisted engineering
Write your program the way you write a book. You write the reasoning in prose and the code beneath it, in the order you thought of it. loom tangle resolves the sections and writes the real files.
Literate programming
A Loom document, written out
# Loom, explained in Loom
Prose first. You are writing for a person — the code lives inside the explanation.
## Greeting
Everything under a heading is prose, until an arrow opens the code.
=>
export function greet(who: string) {
return `Hello, ${who}`
}
## Run it
Nothing closed that block — code runs on to the next heading. A tilde is only for stepping back into prose mid-section.
=>
console.log(greet('world'))
~
Like so.
## Assembling [hello.ts]
A file name in brackets becomes a target.
Code after the arrow holds the composition order.
=>
::[Greeting]
::[Run it]
~
Each anchor pulls in a section it names. loom tangle writes hello.ts in that order.
That's it.
Loom syntax
The whole vocabulary
---FrontmatterFrontmatter opens a chapter and carries its metadata.
#SectionA heading opens a section and names it.
{{ }}WarpWarps bind variables which are used for values interpolation.
[ ]SinkA sink names the file a section tangles into.
{ }SpecifierA specifier gives a section its language or its role.
=>ArrowAn arrow turns from prose into code.
~TildeA tilde turns back from code into prose.
::[ ]AnchorAn anchor transcludes the section or a warp.
Loom CLI
From init to eject
copied
Scaffolds the workspace: a .loom directory holding its config.yaml, and a corpus you make for the documents you write — read in order, top to bottom.
copied
A section names the file its code belongs to. One document can fill several files, and several documents can fill one.
copied
{
"parts": ["The board", "Rules", … ],
"sections": 38,
"sinks": ["board.ts", "store.sql", … ]
}
The whole corpus as one document — prose, headings, bindings, and a pointer into each tangled file. Any site generator can render it.
copied
Loom does not lock you in. There is always a way out: the corpus is archived, and the tangled source is left running.