Function reference#
This page explains the common FrameSeq authoring functions. Each entry follows the same order: what the function creates, a minimal example, a readable signature, its parameters, and its return value.
Generated slides.ts files expose these lowercase functions globally, so imports are not required. Signatures here emphasize how a function is used; for exact TypeScript overloads, complete option interfaces, and the uppercase object API, see the API reference.
On this page#
- Document
- Text
- Lists and reveals
- Semantic objects
- Media and typesetting
- Tables, charts, and icons
- Citations
- Slide layouts
- Regions
- Shapes and connectors
- Themes
- Masters
- Common object methods
- Length helpers
Document#
presentation()#
Starts a new presentation and sets document-wide metadata, canvas size, theme, and typography.
presentation({
title: "Quarterly Review",
author: "Ada Lovelace",
theme: "minimal-academic",
});
Signature
presentation(title) → SlidesDefinition
presentation(options) → SlidesDefinition
Parameters
title—string, optional. A short form for setting only the presentation title.options—SlidesOptions, optional. Sets metadata,theme,ratio, customwidthandheight, a papersizeandorientation,background, presentation-widefontdefaults, abibliographyforcite(), andcitationsoptions.
Returns SlidesDefinition, the presentation root. Most linear documents do not need to store it.
Call presentation() once, before the first slide(). Calling it again starts a new authoring context.
poster()#
Starts a poster: a presentation made for paper, A0 portrait in the poster theme unless the options say otherwise, with its one page already begun.
poster({
title: "Diffusion Language Models",
author: "Ada Lovelace",
institute: "University of Cambridge",
}).grid(3);
Signature
poster(title) → ContentSlideBuilder
poster(options) → ContentSlideBuilder
Parameters
title—string, optional. A short form for setting only the title.options—SlidesOptions, optional. The same options aspresentation();size,orientation, andthemereplace the poster's defaults.
Returns ContentSlideBuilder, the poster's page, so its layout, such as .grid(3), can follow directly. See Posters and print.
figure()#
Starts a figure for a paper: one canvas with no margins, printed at the width it will have on the page, so frameseq pdf gives a page of exactly that size and the layout check judges type in printed points.
figure({ title: "Method", width: 1600, height: 820 });
at("encoder").panel("(a) Encoder layer").canvas().position({ x: 20, y: 20 }).width(620).height(780);
Signature
figure(title) → ContentSlideBuilder
figure(options) → ContentSlideBuilder
Parameters
title—string, optional. A short form for setting only the title.options—FigureOptions, optional.widthandheightare canvas units, 1600 and 900 by default;printWidthis how wide it prints,"170mm"by default, or"85mm"for one column;theme,font, andbackgroundwork as forpresentation().
Returns ContentSlideBuilder, the figure's page, already a canvas. See Posters and print.
slide()#
Starts a slide. Every content command after it belongs to that slide until the next slide() call.
slide("Results");
text("Revenue increased by 42%.");
Signature
slide(name) → ContentSlideBuilder
slide(options) → ContentSlideBuilder
Parameters
name—string, optional. Sets both the internal name and the visible slide title.options—SlideOptions, optional. Separatesname, visibletitle, speakernotes, andallowEmptymetadata.
slide({ name: "result-details", title: "Detailed results" });
slide({ name: "photo" }); // no automatic visible title
Returns ContentSlideBuilder, which provides slide layout methods such as .split() and .canvas().
.notes()#
Adds private speaker notes to a slide.
slide("Results").notes("Pause here and explain the comparison.");
Signature notes(content) → slide
Parameters
content—string, required. Text shown in presenter view and exported to PowerPoint speaker notes.
Notes are not shown on the audience page or in PDF output.
note()#
Adds speaker notes to the current slide without chaining them onto slide(). note(content) and slide().notes(content) produce the same result.
slide("Results");
text("Revenue increased by 42%.");
note("Compare the trend, not the absolute value.");
Signature note(content) → ContentSlideBuilder
Parameters
content—string, required. Text shown in presenter view and exported to PowerPoint speaker notes.
Returns the current slide, so slide methods still chain: note("Pause here").allowEmpty().
Repeated calls append a line instead of replacing the previous note, so a reminder can stay beside the content it explains:
slide("Two comparisons");
text("First measurement");
note("Explain how it was collected.");
text("Second measurement");
note("Contrast it with the first.");
Notes written with slide().notes() are kept and extended in the same way.
.allowEmpty()#
Marks a slide as intentionally empty for the layout checker.
slide({ name: "Pause" }).allowEmpty();
Signature allowEmpty(enabled) → slide
Parameters
enabled—boolean, optional. Defaults totrue.
Text#
text()#
Creates a text object in the current slide region.
text("A normal paragraph");
text("An emphasized sentence").size(30).bold().color("#2563eb");
Signature
text(content) → TextBoxBuilder
text`...` → TextBoxBuilder
Parameters
content—string, required. The text to display.stringsandvalues— tagged-template input. Use this form when the text contains inline LaTeX so backslashes remain intact.
text`Energy and mass satisfy $E = mc^2$.`;
Returns TextBoxBuilder. It supports normal object modifiers and the text roles below.
Text roles#
A role supplies presentation-aware typography. The most recently called role replaces any earlier role on the same text object.
| Method | Meaning | Example |
|---|---|---|
.body() |
Normal paragraph text; the default role | text("Explanation").body() |
.title() |
A manually placed slide heading | text("Architecture").title() |
.hero() |
The primary title on a cover or section slide | text("FrameSeq").hero() |
.subtitle() |
Supporting text below a hero title | text("Slides as code").subtitle() |
.author() |
Author or presenter name | text("Ada Lovelace").author() |
.eyebrow() |
A small uppercase section label | text("Section 01").eyebrow() |
.lead() |
The leading statement on a content slide | text("Latency fell by 42%.").lead() |
.caption() |
A source, footnote, or image caption | text("Source: Example data").caption() |
.quote() |
A short quotation | text("Simplicity is a feature.").quote() |
Every role returns the same TextBoxBuilder, so further modifiers can be chained.
Lists and reveals#
bullets()#
Creates an unordered list whose items are all visible immediately.
bullets("Readable source", "Useful defaults", "Portable output");
Signature bullets(...items) → ElementBuilder
Parameters
items—string[], required. One or more strings, in display order.
Returns ElementBuilder, representing the complete list rather than an individual item.
steps()#
Creates a numbered list whose items are revealed one at a time.
steps("Parse the source", "Build the slide tree", "Render the result");
Signature steps(...items) → ElementBuilder
Parameters
items—string[], required. Item one appears at step1, item two at step2, and so on.
Returns ElementBuilder. PDF and PPTX output include every item.
.showAt()#
Assigns an individual object to a reveal step.
text("First result").showAt(1);
image(chart, "Result chart").showAt(2);
Signature showAt(step) → same object
Parameters
step—number, required. A positive reveal step; steps begin at1.
Print, PDF, and PPTX output show all steps.
Semantic objects#
metric()#
Displays a prominent value with a smaller label that explains it.
metric("42%", "Revenue growth");
Signature metric(value, label) → GroupBuilder
Parameters
value—string, required. The emphasized value, such as"42%"or"18K".label—string, required. A short description of what the value means.
Returns GroupBuilder, so the metric can be styled, placed in a grid, or converted to a card.
metric("42%", "Revenue growth").card().background("#eff6ff");
metric() only displays the supplied strings; it does not calculate data or format values. Use text() when the content is a sentence rather than a value-label pair.
card()#
Creates a bordered surface containing a title and optional supporting text.
card("Portable", "Export HTML, PDF, and editable PPTX.");
Signature card(title, content) → GroupBuilder
Parameters
title—string, required. The card heading.content—string, optional. Short supporting copy below the heading.
Returns GroupBuilder, representing the whole card as one styleable object.
group()#
Combines existing objects into one vertical, independently styleable object.
group(
text("Revenue").bold(),
text("$1.2M").size(42),
).card();
Signature group(...items?) → GroupBuilder
Parameters
items—Array<ElementBuilder | string>, optional. Existing FrameSeq objects, in vertical order. A string selects an object by the name given to it with.as(), so grouping needs no local variables:
rect("Parse").as("parse");
rect("Build").as("build");
group("parse", "build").row().gap(16);
Returns GroupBuilder.
The child objects are removed from the current region and inserted once inside the group. This keeps the linear syntax: create the children first, then define their parent.
With no items, group() creates an empty container in the current flow. To write the container first and its contents afterwards, name it with at() instead:
at("panel").card().padding(24);
text("Revenue").bold();
text("$1.2M").size(42);
ref()#
Selects an object or region by the name given to it with .as() or at(), so styling can happen after the content is written.
rect("Parse").as("parse");
rect("Build").as("build");
ref("parse").fill("#dbeafe");
ref("build").fill("#dbeafe");
Signature ref(name) → ElementBuilder
Parameters
name—string, required. A name from.as()or a region path fromat().
Returns the builder that matches the object: shapes keep .fill(), .stroke(), and .strokeWidth(), connectors keep .arrow(), .from(), and .to(), and containers keep .row(), .gap(), and the content methods. Every object keeps the common modifiers, including .style({ ... }) for CSS that has no dedicated method.
ref() searches the current slide, and reports the available names when it finds nothing.
gridSection()#
Arranges supplied objects in a local grid inside the normal top-to-bottom slide flow.
gridSection(
3,
metric("42%", "Growth").card(),
metric("18K", "Users").card(),
metric("99.9%", "Uptime").card(),
).gap(20);
Signature
gridSection(columns, ...items) → GridSectionBuilder
Parameters
columns—number | string, required. An integer from1to12creates equal columns. A CSS grid-template string creates custom tracks, for example"1fr 2fr".items—Array<ElementBuilder | string>, optional. Every supplied object becomes one cell, in source order. Strings select objects by name, as ingroup().
In the direct form, every following object becomes one cell.
Returns GridSectionBuilder, with .columns() and container modifiers such as .gap(), .align(), and .padding().
Content written before and after gridSection() stays in the ordinary slide flow. Use slide().grid() when the entire slide body should be divided into regions.
Calling gridSection(columns) without items creates an empty grid in the current flow. When the objects should be written before the grid, name them with .as() and collect them afterwards: gridSection(2, "quality", "accuracy").
Media and typesetting#
image()#
Creates an image object in the current region.
const diagram = new URL("./assets/diagram.png", import.meta.url).href;
image(diagram, "Compiler pipeline").width(percent(100)).radius(18);
Signature image(src, alt) → ElementBuilder
Parameters
src—string, required. An imported asset URL, data URL, or public URL.alt—string, optional. Accessible alternative text. Defaults to an empty string.
Returns ElementBuilder.
code()#
Creates a preformatted code block.
code(`const answer = 42;`, "ts");
Signature code(content, language) → ElementBuilder
Parameters
content—string, required. Literal code to display.language—string, optional. Language metadata; defaults to"ts". FrameSeq does not currently apply syntax highlighting from this value.
Returns ElementBuilder.
math()#
Renders one standalone LaTeX-compatible equation with KaTeX.
math`\int_0^1 x^2\,dx = \frac{1}{3}`;
Signature
math(content) → ElementBuilder
math`...` → ElementBuilder
Parameters
content—string, required. Equation source without$$delimiters. The tagged-template form preserves LaTeX backslashes.
Returns ElementBuilder.
Use inline $...$ inside text when a formula belongs in a sentence.
typst()#
Compiles a static Typst fragment to SVG during development and export.
typst`
#table(columns: 2, [Model], [Accuracy], [A], [94.6%])
`.width(720);
Signature
typst(content) → ElementBuilder
typst`...` → ElementBuilder
Parameters
content—string, required. A Typst fragment, not a complete project. Tagged fragments are static and do not accept JavaScript interpolation.
Returns ElementBuilder containing the compiled graphic.
Requires the optional @myriaddreamin/typst-ts-node-compiler package.
typstFile()#
Loads and compiles a Typst fragment from a separate file.
typstFile("./figures/results.typ").width(720);
Signature typstFile(path) → ElementBuilder
Parameters
path—string, required. A path relative toslides.ts. The file is watched during development.
Returns ElementBuilder containing the compiled graphic.
latex()#
Compiles a static LaTeX body fragment to an embedded graphic.
latex`
\begin{tabular}{lr}
Model & Accuracy \\
FrameSeq & 94.6\% \\
\end{tabular}
`.width(720);
Signature
latex(content) → ElementBuilder
latex`...` → ElementBuilder
Parameters
content—string, required. A LaTeX body fragment. Do not include\documentclassor a complete document.
Returns ElementBuilder containing the compiled graphic.
Requires the optional node-tectonic package. Use math() for ordinary equations; latex() is most useful for existing tabular content or package-based typesetting.
latexFile()#
Loads and compiles a LaTeX body fragment from a separate file.
latexFile("./tables/results.tex").width(720);
Signature latexFile(path) → ElementBuilder
Parameters
path—string, required. A path relative toslides.ts.
Returns ElementBuilder containing the compiled graphic.
Tables, charts, and icons#
table()#
Adds a table. The first row is the heading, and columns whose cells are all quantities align right.
table([
["Model", "Accuracy", "Latency"],
["Baseline", "91.2%", "18 ms"],
["FrameSeq", "94.6%", "12 ms"],
]);
Signature table(rows) → TableBuilder
Parameters
rows—Array<Array<string | number>>, required. Each row as an array of cells. Cells may hold inline math between$signs.
Returns TableBuilder, with the common object methods and:
.header(rows)— how many of the first rows are headings:1by default,0for none..columnAlign(...alignments)—"left","center", or"right"for each column from the first..striped(enabled)— shade every other body row.
PowerPoint export makes it an editable PowerPoint table, and Typst export a native #table.
chart()#
Adds a chart drawn from the data written beside it.
chart("bar", { Q1: 12, Q2: 18, Q3: 25 }).unit("%");
chart("line", { labels: ["Jan", "Feb", "Mar"], series: { Revenue: [3, 5, 4], Cost: [2, 2, 3] } });
Signature chart(kind, data) → ChartBuilder
Parameters
kind—"bar" | "hbar" | "line" | "pie" | "donut", required.data— required. One series as{ label: value }, or several as{ labels: string[]; series: Record<string, number[]> }with one value per label. A pie or donut takes one series of values that are not negative.
Returns ChartBuilder, with the common object methods and:
.unit(suffix)— write values with a unit, such as"%"or" ms"..values(show)— show or hide the value beside each bar, point, or slice..legend(show)— show or hide the legend..max(value)— fix the top of the value axis..colors(...colors)— colour the series, or a pie's slices, in order.
The chart fills its region's width at 16:9 unless .width() or .height() says otherwise. PowerPoint export makes it an editable PowerPoint chart.
qr()#
Adds a QR code for a link or any text.
qr("https://pride7.github.io/frameseq/").width(220);
Signature qr(text) → ElementBuilder
Parameters
text—string, required. The link or text to encode.
Returns ElementBuilder. The code is 200 pixels square unless .width() says otherwise, dark on light with a quiet margin.
icon()#
Adds an icon from the Lucide set, drawn in the text colour at the font size.
icon("rocket").size(64).color("#2563eb");
Signature icon(name) → ElementBuilder
Parameters
name—IconName, required. An icon's name; TypeScript completes the names and rejects one that does not exist.
Returns ElementBuilder; .size() sets the icon's size and .color() its colour. A built presentation includes only the icons its source names as strings.
Citations#
cite()#
Cites works from the presentation's bibliography and returns the marker to write into the text.
text(`Attention replaced recurrence ${cite("vaswani2017")}.`);
Signature cite(...keys) → string
Parameters
keys—string[], at least one. Keys of the presentation'sbibliography.
Returns string: [1] or [1, 2], numbered in the order works are first cited, or (Vaswani et al., 2017) with citations: { style: "author-year" }. The works a slide cites are listed at its foot unless citations: { footnotes: false }. See Citations and references.
footnote()#
Adds a footnote to the current slide and returns its marker.
text(`Measured on one GPU${footnote("An NVIDIA A100.")}.`);
Signature footnote(content) → string
Parameters
content—string, required. The footnote's text.
Returns string, a superscript number such as ¹, counted from 1 on each slide.
references()#
Adds the list of works the presentation cites.
slide("References");
references();
Signature references(options) → GroupBuilder
Parameters
options—{ all?: boolean }, optional.all: trueadds the works the bibliography holds but the talk never cited, after the cited ones.
Returns GroupBuilder. The list is filled once the document has run, so it includes citations made after it.
Slide layouts#
Without a layout method, content is placed in one vertical column in source order.
.cover()#
Applies the cover-slide layout and cover text styles.
slide({ name: "Cover" }).cover();
text("FrameSeq").hero();
text("Write slides as TypeScript").subtitle();
text("Ada Lovelace").author();
Signature cover() → slide
Use text roles to create the visible cover content; .cover() does not generate a title by itself.
.split()#
Divides the whole slide body into left and right regions.
slide("Architecture").split("40:60");
image(diagram, "Pipeline");
right();
bullets("Parse", "Render", "Export");
Signature split(ratio) → slide
Parameters
ratio—"left:right" | number | [number, number], optional. Defaults to"1:1". Examples:"40:60",0.4,40, and[2, 3].
Existing content moves to the left region. Subsequent content also starts on the left; call right() to switch regions.
.grid()#
Divides the whole slide body into equal-width regions.
slide("Results").grid(3);
cell(0); metric("42%", "Growth");
cell(1); metric("18K", "Users");
cell(2); metric("99.9%", "Uptime");
Signature grid(columns, gap) → slide
Parameters
columns—number, required. An integer from1to12.gap—number | string, optional. Space between the regions; the active theme supplies the default.
Use cell(index) to select a zero-based region. Use gridSection() for a grid between ordinary content above and below it.
.center()#
Centers the normal slide body horizontally and vertically.
slide({ name: "Conclusion" }).center();
text("Make the structure visible.").quote();
Signature center() → slide
This is intended for a single quotation, conclusion, or key message.
.fullBleed()#
Fills the slide body with one image.
slide({ name: "Landscape" }).fullBleed(photo, "Mountain landscape");
Signature fullBleed(src, alt) → slide
Parameters
src—string, required. The image URL.alt—string, optional. Accessible alternative text; defaults to an empty string.
Use a slide without a visible title when the image should occupy all available space.
.canvas()#
Changes the slide body into a freeform coordinate system.
slide({ name: "System map" }).canvas();
text("Compiler").position({ x: 80, y: 90 }).width(300).size(32).bold();
Signature canvas() → slide
Canvas coordinates use the presentation canvas, which defaults to 1600 × 900. Prefer normal flow, .split(), .grid(), or gridSection() for ordinary content slides.
Regions#
left() and right()#
Select the destination for subsequent content on a slide using .split().
left();
text("Before");
right();
text("After");
Signature
left() → RegionBuilder
right() → RegionBuilder
Returns the selected RegionBuilder. Calling either function changes the active authoring region.
cell()#
Selects a region on a slide using .grid().
cell(1);
text("This goes in the second cell.");
Signature cell(index) → RegionBuilder
Parameters
index—number, required. A zero-based cell number;0is the first cell.
Returns the selected RegionBuilder and makes it active.
at()#
Moves the authoring cursor to a region addressed by a path, creating the containers on the way. Composition therefore stays flat: one statement per object, no nesting and no closing call.
at("cell0/now").card();
text("Q3").eyebrow();
bullets("Anchors", "Region paths");
at("cell1/next").card();
text("Q4").eyebrow();
at("cell0/now");
text("Merged into main").caption();
Signature at(path) → RegionBuilder
Parameters
path—string, required. Segments separated by/. The first segment may name a region the layout already owns:main,left,right, orcell0,cell1, and so on. Every other segment is a container that FrameSeq creates the first time it is used. An empty path is the same asmain().
Returns the selected RegionBuilder and makes it active. Revisiting a path returns the same region and appends to it, so a page can be written in whatever order reads best. Paths are scoped to their slide, and FrameSeq also registers them as anchor names, so line().from("stages.left") can connect to a positioned region.
Set the layout of a region where it first appears: at("pipeline").row().gap(24).
.panel()#
Frames a region as one panel of a figure, such as "(a) Encoder layer": a light outline, rounded corners, and a bold title in its top-left corner, with a leading tag such as (a) in a quieter colour.
at("encoder").panel("(a) Encoder layer").canvas().position({ x: 20, y: 20 }).width(620).height(780);
shape("rounded", "Attention").as("attention").position({ x: 190, y: 380 }).width(240).height(58);
Signature .panel(title) → RegionBuilder
Parameters
title—string, required. The panel's title. A leading tag in parentheses, such as(a)or(b), is set apart in the muted colour.
Returns the same RegionBuilder. Its contents move with it; content in a row or a column starts below the title, and on a canvas, coordinates count from the panel's corner, so keep objects about 70 pixels down.
main()#
Returns content placement to the slide's primary region.
right();
text("Right side");
main();
text("Back to the primary region");
Signature main() → RegionBuilder
Returns the normal body, left split region, or first whole-slide grid cell, depending on the current layout.
gap()#
Changes the spacing between children in the active region.
gap(32);
bullets("More", "Space", "Between objects");
Signature gap(value) → RegionBuilder
Parameters
value—number | string, required. Numbers mean pixels; strings may use CSS units.
Returns the active RegionBuilder. To change a local grid, chain the method instead: gridSection(...items).gap(20).
Shapes and connectors#
Shapes are normal FrameSeq objects. Exact placement is intended for a slide using .canvas().
rect()#
Creates a rectangular diagram node with an optional centered label.
rect("Input")
.position({ x: 80, y: 140 })
.width(240)
.height(100)
.fill("#dbeafe")
.stroke("#2563eb");
Signature rect(label) → ShapeBuilder
Parameters
label—string, optional. Defaults to an empty string.
Returns ShapeBuilder, which adds .fill(), .stroke(), .strokeWidth(), .tone(), .shadow(), and .dashed() to the common modifiers.
circle()#
Creates a circular diagram node with an optional centered label.
circle("Model").position({ x: 520, y: 110 }).width(160);
Signature circle(label) → ShapeBuilder
Parameters
label—string, optional. Defaults to an empty string.
Returns ShapeBuilder. Its width controls the diameter unless a height is set explicitly.
shape()#
Creates a diagram shape: a vector outline with an optional label set in the outline's own room. There are 27 kinds, from flowchart symbols to block arrows, and each one exports to PowerPoint as its native shape.
shape("diamond", "Cached?").as("check").tone("amber");
shape("cylinder", "Postgres").position({ x: 980, y: 200 }).tone("purple").shadow();
shape("pill", "Start").tone("green", "solid").width(180).height(56);
Signature shape(kind, label) → ShapeBuilder
Parameters
kind—ShapeKind, required. Basic outlines:"rect","rounded","pill","ellipse","circle","diamond","triangle","pentagon","hexagon","octagon","parallelogram","trapezoid","star","plus". Diagram symbols:"cylinder"(a database),"document","note","cube","cloud","callout". Arrows and steps:"chevron","step","arrow-right","arrow-left","arrow-up","arrow-down","arrow-both".label—string, optional. Defaults to an empty string. Inline math between$signs is supported.
Returns ShapeBuilder. Each kind has a usual size that .width() and .height() replace. .tone(color, style) paints it from one colour, "soft" (the default), "solid", or "outline", in one of "accent", "blue", "sky", "teal", "green", "lime", "amber", "orange", "red", "pink", "purple", "indigo", "gray", or any CSS colour. .shadow() casts a soft shadow and .dashed() dashes the outline.
polygon()#
Creates a diagram shape through corners of your own, for an outline no shape() kind has, such as an encoder that narrows from one side to the other. It exports to PowerPoint as an editable freeform.
polygon([[0, 0], [64, 47], [64, 153], [0, 200]], "Encoder").position({ x: 190, y: 370 }).tone("gray");
polygon([[60, 0], [120, 100], [0, 100]]).as("peak").width(180).height(120).tone("amber", "solid");
Signature polygon(points, label) → ShapeBuilder
Parameters
points—Array<[number, number]>, required. The corners in order around the outline, in pixels from any origin; at least three, spanning some width and some height.label—string, optional. Defaults to an empty string. Centred in the polygon's box; inline math between$signs is supported.
Returns ShapeBuilder. The polygon is as large as its corners span, and .width() and .height() stretch it. It takes .tone(), .fill(), .stroke(), .dashed(), .shadow(), and placement by name like any shape.
line()#
Creates a vector connector between two canvas coordinates.
line({ x1: 320, y1: 190, x2: 520, y2: 190 })
.stroke("#2563eb")
.strokeWidth(4)
.arrow("end");
Signature line(points) → LineBuilder
Parameters
points—{ x1: number; y1: number; x2: number; y2: number }, optional. Omit it when both ends use.from()and.to().
Returns LineBuilder, which provides .stroke(), .strokeWidth(), .arrow("none" | "start" | "end" | "both"), .from(), .to(), .via(...stops), .route("straight" | "elbow" | "curve"), .label(text), and .dashed(). An elbow route turns at right angles and keeps clear of the other objects on the canvas; .via() runs the connector through named objects or [x, y] points on the way; a label sits halfway along the connector.
cells()#
Creates a row of equal cells from a list of values, or a grid from rows: tokens, embeddings, codes, attention masks, and similarity matrices. A number from 0 to 1 shades its cell, words label it, and null masks it.
cells([0.3, 0.9, 0.1, 0.6]).tone("amber").framed().as("codes").position({ x: 80, y: 360 });
cells([[1, 0.1], [0.1, 1]]).tone("indigo").cell(76).labels((r, c) => `$I_${r + 1} \\cdot T_${c + 1}$`);
Signature cells(values) → CellsBuilder
Parameters
values—Array<number | string | null>for a row, or rows of them of the same length, required. Numbers run from 0 to 1.
Returns CellsBuilder, which provides .tone(color), .cell(width, height), .gap(pixels), .labels(words), .size(pixels), and .framed(), besides placement and naming; connectors reach the set as a whole.
junction()#
Creates the point where connectors meet or split, such as the place a skip connection leaves the main path, or, with a sign, the small round operator where streams are added or multiplied.
junction().as("split").above("plus", 50);
junction("+").as("plus").above("embedding", 48);
line().from("split.right").to("norm.right").route("elbow").arrow();
Signature junction(sign) → ShapeBuilder
Parameters
sign—string, optional. Defaults to an empty string, which draws a 10-pixel dot in the connectors' colour. A sign such as"+"or"×"draws a 32-pixel outlined circle with the sign in it.
Returns ShapeBuilder. Name it with .as(), place it with .position() or a placement such as .above(), and connect to it like any object; .fill(), .stroke(), and .width() restyle it.
.as()#
Names a diagram object so connectors and placements can reference it instead of repeating coordinates. Names are unique within a slide.
rect("Encoder").as("enc").position({ x: 80, y: 140 }).width(200).height(100);
Signature .as(name) → the same object
Parameters
name—string, required. Letters, digits,_, and-, starting with a letter or_.
.from() and .to()#
Attach a connector to named objects. FrameSeq resolves the endpoints before rendering, so a connector follows its nodes when their coordinates change.
line().from("enc").to("dec").arrow("end");
line().from("enc.right", { dy: -20 }).to("dec.top-left");
Signature .from(reference, offset) → the same connector, .to(reference, offset) → the same connector
Parameters
reference—string, required. A name such as"enc", or a name and an anchor such as"enc.right". Anchors arecenter,top,bottom,left,right,top-left,top-right,bottom-left, andbottom-right. Without an anchor FrameSeq uses the edges that face the other end.offset—{ dx?: number; dy?: number }, optional. Shifts the endpoint in canvas pixels.
.rightOf(), .leftOf(), .above(), and .below()#
Place an object next to a named object instead of computing its coordinates.
rect("Decoder").as("dec").rightOf("enc", 140);
text("shared vocabulary").caption().below("enc", 16);
Signature .rightOf(name, gap) → the same object, and likewise for the other three
Parameters
name—string, required. The name of a positioned object on the same canvas.gap—number, optional. Canvas pixels between the two objects. Defaults to40horizontally and24vertically.
The placed object is centred on the other axis and needs no size of its own. The referenced object needs a resolvable box: rect() defaults to 240 x 96 and circle() to 160 x 160.
.centerOn(), .alignTop(), and .alignLeft()#
Centre an object on a named object, or match one of its edges. alignTop() and alignLeft() change one axis only, so they chain onto another placement.
circle("Badge").as("badge").centerOn("dec").width(48);
rect("Cache").as("cache").rightOf("enc", 60).alignTop("enc");
Signature .centerOn(name) → the same object, .alignTop(name) → the same object, .alignLeft(name) → the same object
Parameters
name—string, required.
spacer()#
Adds empty space that takes whatever room is left over, which pushes the objects after it to the far end of the region.
at("footer").row().gap(0);
text("FrameSeq").caption();
spacer();
text("2026").caption();
Signature spacer(size) → the spacer object
Parameters
size—number, optional. The share of the free space this spacer takes, relative to the other spacers in the same region. Defaults to1.
A spacer only means something inside a row(), column(), or grid, because a block container has no free space to hand out. It renders nothing and is never reported as an empty slide.
.selfAlign() and .centerSelf()#
Align one object across the axis of the row or column that holds it, without moving its siblings and without a canvas. A column aligns horizontally, a row aligns vertically.
text("A framed pull quote").width(520).centerSelf();
image(logo, "Logo").width(160).selfAlign("end");
Signature .selfAlign(value) → the same object, .centerSelf() → the same object
Parameters
value—"start" | "center" | "end" | "stretch", required..centerSelf()is.selfAlign("center").
Objects stretch across the axis by default, so an object only moves once it has a size of its own: give it .width(...) in a column or .height(...) in a row. .align() sets the same alignment for every child of a container, while .selfAlign() overrides it for one object. To move the text inside an object instead of the object itself, use .textAlign(); to move it along the region rather than across it, use .justify() on the container or a spacer().
.anchor()#
Positions an object against its container instead of by coordinates.
at("stages").row().gap(80).anchor("center");
at("legend").column().gap(8).anchor("bottom-right", 40);
Signature .anchor(position, margin) → the same object
Parameters
position—string, required. One ofcenter,top,bottom,left,right,top-left,top-right,bottom-left,bottom-right.margin—number, optional. Distance from the edge in canvas pixels; defaults to0and is ignored forcenter.
The browser resolves the result, so an object placed this way becomes its own coordinate space. Anchor connectors to the objects inside it rather than across it, and put those connectors inside the same container.
A row or column placed this way still resolves its children, so a diagram can be written without a single coordinate:
slide("Pipeline").canvas();
at("stages").row().gap(80).anchor("center");
rect("Parse").as("parse");
rect("Build").as("build");
line().from("parse").to("build").arrow("end");
See Shapes and connectors for the full anchor model and its limits.
Themes#
themes#
Contains the complete definitions of all built-in themes.
presentation({ title: "My Talk", theme: themes.paper });
Most documents can use the shorter theme name, such as theme: "paper". The themes object is useful when code needs a complete theme definition.
defineTheme()#
Creates a reusable theme by overriding selected design tokens.
const ocean = defineTheme({
name: "ocean",
extends: "blank",
colors: { accent: "#007c91" },
});
presentation({ title: "Ocean", theme: ocean });
Signature defineTheme(options) → ThemeDefinition
Parameters
options.name— unique theme name, required.options.extends— built-in theme name or theme definition, optional. Defaults to"blank".options.colors,fonts,spacing,radii,chrome— partial token groups.options.family,coverLayout,coverBackground— optional theme-level behavior.
Returns a complete ThemeDefinition that can be passed to presentation() or extended by another theme.
See Themes for all token names and built-in previews.
Masters#
master()#
Starts a master page: objects drawn behind every slide that uses it, as a slide master is in PowerPoint. The objects after it belong to the master until the next slide() or master() call.
master("content");
rect().position({ x: 0, y: 0 }).width(1280).height(96).fill("#1e3a8a");
placeholder("title").position({ x: 60, y: 0 }).width(1160).height(96).color("#ffffff");
text("{page} / {total}").position({ x: 1120, y: 676 }).width(100).textAlign("right").caption();
Signature master(name) → MasterBuilder
Parameters
name—string, required. Letters, digits,_, and-, starting with a letter. Covers are drawn on the master named"cover"and every other slide on the one named"content"; any other name is used by the slides that ask for it with.master().
Returns MasterBuilder, the master page. .background() paints the page of every slide drawn on it.
A master page is a canvas: place its objects with .position(). Text on it may show {title}, {subtitle}, {author}, {institute}, and {date} from the presentation, {page} and {total}, and {slide}, the slide's own title. Each name is written once per presentation. See Masters and templates.
placeholder()#
Marks, on a master page, where the slides drawn on it put their own content.
master("cover");
placeholder("title").position({ x: 500, y: 180 }).width(700).height(220).size(60);
placeholder().position({ x: 500, y: 420 }).width(700).height(200);
Signature placeholder(role) → ElementBuilder
Parameters
role—"body","title","subtitle", or"author", optional. Defaults to"body": everything the slide holds flows inside it."title"takes a slide's title, or a cover's.hero()text;"subtitle"and"author"take a cover's.
Returns the placeholder. .position(), .width(), and .height() give its box; text settings such as .size(), .color(), .weight(), and .textAlign() style the text it holds on every slide, unless the slide sets them itself; .justify("start" | "center" | "end") puts that text at the top, the middle, or the foot of the box.
A master has at most one placeholder of each role. A placeholder written outside a master is an error.
.master()#
Draws a slide on another master, or on none.
slide("Part two").master("section");
slide({ name: "Photo" }).master(false).fullBleed(photo, "The lab at night");
Signature master(name) → slide
Parameters
name—stringorfalse, required. The name of a master the presentation defines, orfalsefor no master. A name the presentation does not define is reported with the slide that asked for it.
Common object methods#
Content functions return the object they create. These methods change that object and return the same builder, so calls can be chained.
| Method | Parameters | Meaning |
|---|---|---|
.size(value) / .fontSize(value) |
value: Length |
Set font size. |
.weight(value) / .fontWeight(value) |
value: number | string |
Set font weight. |
.bold() |
None | Set font weight to 700. |
.color(value) |
value: string |
Set text or foreground color. |
.background(value) |
value: string |
Set the background. |
.width(value) / .height(value) |
value: Length |
Set object dimensions. |
.minWidth(value) / .minHeight(value) |
value: Length |
Set minimum dimensions. |
.maxWidth(value) / .maxHeight(value) |
value: Length |
Cap the dimensions; how text is kept to a readable measure. |
.padding(vertical, horizontal) |
vertical: Length; horizontal: Length, optional |
Set inner spacing. |
.padding(sides) |
sides: { top?, right?, bottom?, left? } |
Set inner spacing per side; an omitted side is zero. |
.margin(vertical, horizontal) |
vertical: Length; horizontal: Length, optional |
Set outer spacing. |
.margin(sides) |
sides: { top?, right?, bottom?, left? } |
Set outer spacing per side; an omitted side is zero. |
.gap(rows, columns) |
rows: Length; columns: Length, optional |
Set spacing between container children; one value covers both axes. |
.border(value) |
value: string |
Set a complete CSS border. |
.radius(value) |
value: Length |
Set corner radius. |
.lineHeight(value) |
value: number | string |
Set text line height. |
.textAlign(value) |
value: left | center | right |
Set text alignment. |
.selfAlign(value) / .centerSelf() |
value: start | center | end | stretch |
Align this object across the axis of its container. |
.opacity(value) |
value: number |
Set opacity, normally from 0 to 1. |
.clip(enabled) |
enabled: boolean, optional |
Clip children to this object's bounds; defaults to true. |
.position(bounds) |
bounds: { x?: Length; y?: Length } |
Use absolute canvas coordinates. |
.rotate(degrees) |
degrees: number |
Rotate the object. |
.fit(minimum) |
minimum: number, optional |
Shrink the text inside until the object holds it, down to minimum of its size; 0.5 by default. |
.style(classes) |
classes: string |
Add Tailwind utility classes. |
.style(properties) |
properties: CSS values |
Add inline CSS properties. |
.className(value) |
value: string |
Add one or more CSS classes. |
All methods in this table return the same object. Objects also provide .row(), .column(), .stack(), .grid(), .canvas(), .center(), .align(), .justify(), .wrap(), and .alignContent(), which arrange their own children, plus .selfAlign(), .centerSelf(), and .grow(), which describe how they sit inside the container that holds them. See Styling for accepted values and precedence rules, and Which axis a modifier moves for choosing between them.
Length helpers#
Length helpers make a CSS unit explicit. They return strings and can be used anywhere FrameSeq accepts Length.
px(20) // "20px"
pt(20) // "20pt"
mm(20) // "20mm"
rem(2) // "2rem"
percent(50) // "50%"
vw(40) // "40vw"
vh(30) // "30vh"
text("Label").size(pt(24)).width(percent(50));
Plain numeric lengths are interpreted as pixels. On a presentation made for paper, pt() and mm() are printed sizes on the sheet, converted to canvas units; see Posters and print.