forma Reference#
forma is a declarative language for describing solids. A document is a list of top-level
blocks; geometry is written by nesting blocks, where a block's children are its operands.
The evaluator turns a document into a tree of immutable geometry nodes, and the
Manifold CSG kernel - compiled to WebAssembly - solves
that tree into meshes.
param height { type = number default = 20 min = 8 max = 40 }
model "riser" {
part "body" {
color = "#6f7d8c"
difference {
extrude {
height = var.height
rounded_rect { size = [40, 20] radius = 4 center = true }
}
translate {
offset = [0, 0, 3]
cylinder { radius = 5 height = var.height }
}
}
}
}
This reference documents every construct in the language and every function the JavaScript package exports. For a tour of the project itself - how to run the editor, how to consume the library from Node - see the top-level README.
Learn the language#
Read these in order the first time.
| Page | What it covers |
|---|---|
| Document structure | The four top-level blocks, the evaluation pipeline, nesting and implicit union, dimensionality |
| Syntax | Comments, numbers, strings, identifiers, labels, the rule that a newline ends an attribute |
| Expressions | Values, operators, precedence, truthiness, interpolation, member access |
| Scope and names | What is in scope where, var., shadowing, component isolation |
| Control flow | for and if / else if / else |
Declarations#
The four blocks that may appear at the top level of a document.
| Declaration | Description |
|---|---|
param |
An input, exposed in the editor as a control and readable as var.NAME |
local |
A named value, computed once |
component |
A reusable parameterised block, callable like any builtin |
model |
Something to render. A document may declare several |
Shapes#
Leaf blocks. They take attributes and never contain other blocks.
| Block | Dimensionality | Description |
|---|---|---|
rect |
2D | An axis-aligned rectangle |
rounded_rect |
2D | A rectangle with true arcs at the corners |
circle |
2D | A circle, from a radius or a diameter |
ellipse |
2D | A circle scaled to two exact radii |
regular_polygon |
2D | An n-gon, sized across flats, across corners, or by radius |
stadium |
2D | A rectangle fully rounded on its short axis |
polygon |
2D | An explicit outline, or several contours with holes |
box |
3D | An axis-aligned cuboid |
sphere |
3D | A sphere |
cylinder |
3D | A cylinder, or a frustum from two radii |
cone |
3D | A cone, or a truncated cone |
torus |
3D | A ring, optionally a partial arc |
2D shapes cannot be rendered on their own - extrude or
revolve them first.
Operations#
Blocks that take geometry as children and produce new geometry.
| Block | Takes | Description |
|---|---|---|
union |
2D or 3D | Everything added together |
difference |
2D or 3D | The first child, with every later child cut out of it |
intersection |
2D or 3D | Only what every child shares |
translate |
2D or 3D | Moves geometry |
rotate |
2D or 3D | Turns geometry about the origin |
scale |
2D or 3D | Scales geometry about the origin |
mirror |
2D or 3D | Reflects geometry in a plane through the origin |
extrude |
2D → 3D | Sweeps a profile along Z, with optional twist and taper |
revolve |
2D → 3D | Turns a profile about the Y axis into a solid of revolution |
project |
3D → 2D | The shadow of a solid on the XY plane |
slice |
3D → 2D | The cross-section of a solid at one Z |
offset |
2D | Grows or shrinks an outline |
hull |
2D or 3D | The convex hull of everything inside |
refine |
3D | Subdivides edges longer than a limit |
simplify |
2D or 3D | Removes vertices within a tolerance |
smooth |
3D | Rounds edges below a sharpness threshold |
trim |
3D | Cuts a solid with a half-space |
align |
2D or 3D | Moves geometry so a measured feature of its bounding box lands where you say |
Scene#
| Block | Description |
|---|---|
part |
A separately coloured piece of the rendered scene |
Expressions#
| Page | What it covers |
|---|---|
| Functions | abs, min, len, range, sin, and the rest of the builtin functions |
| Constants | pi and e |
| Operators | Arithmetic, comparison, logic, and what each accepts |
JavaScript API#
src/ is the library; the editor is one consumer of it. Everything below is exported from
the package root and typed by hand-written declarations.
| API | Description |
|---|---|
render |
Compile a document and evaluate one model into renderable parts |
describeParameters |
Read a document's declared params without rendering |
EvaluationContext |
The digest cache and the owner of every WASM object |
GeometryNode |
The immutable, content-addressed geometry IR |
loadKernel, setQuality, resetQuality |
Loading and tuning the Manifold module |
toRenderMesh, toBinarySTL |
Turning a solid into buffers or a file |
Vector, Angle, Transform |
The value types the evaluator works in |
Program, Evaluator, parse, tokenize, … |
The compiler stages, and the block and function registries |
Errors#
Every error message, what raises it, and what to change - the language's errors in one place, grouped by the stage that raises them.
Running it#
| Tool | What it is |
|---|---|
| Command line | forma render part.forma -o part.stl - solving a document in a build, with no browser |
| Editor | The same kernel in a browser, with live previews and a control per declared param |
| MCP server | The language as a tool an agent can write, with every document it produces solved before it answers |