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
- Slide layouts
- Regions
- Shapes and connectors
- Themes
- 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,background, and presentation-widefontdefaults.
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.
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.
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).
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(), and .strokeWidth() 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.
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(), and .to().
.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.
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. |
.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"
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.