| name | typst |
| description | Build, edit, debug, and polish Typst documents, templates, reports, papers, slides, posters, and data-driven publications. Use when working with `.typ`, `typst.toml`, Typst package imports, Typst Universe templates/packages, TinyMist diagnostics or preview, CSV/JSON/YAML/TOML data loading, Lilaq plots, or converting repeated document styling into reusable Typst variables, functions, modules, and show rules. |
Typst
Use Typst as a programmable document system, not just a markup format. Inspect the existing project first, reuse packages and templates aggressively, and keep a fast compile or preview loop running while editing.
Workflow
- Inspect the project shape:
typst.toml, entrypoint .typ files, local modules, data files, package imports, fonts, and current compile errors.
- Search Typst Universe before implementing custom layout, plotting, theorem boxes, slides, CVs, tables, glossaries, diagrams, syntax highlighting, invoices, or institutional templates: https://typst.app/universe/search/.
- Prefer current Universe packages/templates over hand-rolled code:
- package import:
#import "@preview/package:version": item
- aliased package import:
#import "@preview/lilaq:0.6.0" as lq
- template start:
typst init @preview/template-name:version
- Set up feedback:
- If
tinymist exists, use tinymist compile main.typ, tinymist compile --save-lock main.typ, tinymist preview --no-open main.typ, and tinymist test main.typ.
- If
tinymist is missing and cargo exists, install it with cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist-cli.
- If TinyMist is unavailable or broken, fall back to
typst compile main.typ.
- Make the smallest document change that compiles, then iterate from diagnostics and rendered output.
Idioms To Prefer
- Put repeated values in variables: colors, margins, columns, names, labels, measurements, and switches.
- Put repeated structure in functions or modules, not pasted blocks.
- Use dictionaries and arrays for document metadata, table rows, figure specs, and style presets.
- Use
set rules for defaults and show rules for semantic styling.
- Keep package versions pinned. Update versions only when there is a reason.
- Use
--root when assets or data paths are project-root relative.
- Use semantic line breaks for prose: one sentence or meaningful clause per source line; do not reflow paragraphs just to hit a column width.
- Prefer semantic wrappers like
#metric-card(..), #result-table(..), or #chapter-note[..] over scattered formatting.
Data And Plots
Prefer data files over pasted values. Typst can load csv, json, yaml, toml, xml, and raw files.
For CSVs with headers, start with:
#let rows = csv("data.csv", row-type: dictionary)
#let xs = rows.map(row => int(row.year))
#let ys = rows.map(row => float(row.value))
For in-document plots, prefer Lilaq before exporting plots from another tool. Check the current package page and docs first:
#import "@preview/lilaq:0.6.0" as lq
#lq.diagram(
title: [CSV-backed trend],
xlabel: [Year],
ylabel: [Value],
lq.plot(xs, ys, mark: "o", label: [Observed]),
)
TinyMist Checks
TinyMist is useful because it provides CLI compile/test/preview behavior plus language-server context.
Use these checks when practical:
tinymist --version
tinymist compile main.typ main.pdf
tinymist compile --save-lock main.typ
tinymist preview --no-open main.typ
tinymist test main.typ
Notes:
tinymist compile --save-lock writes tinymist.lock in the current directory unless --lockfile is passed.
tinymist preview --no-open main.typ starts local preview servers and should be stopped after verification.
tinymist test runs Typst test functions such as #let test-name() = [...]; a document with no tests can still be useful as a smoke check.
tinymist lsp is for editor/LSP clients; do not leave it running in a noninteractive shell.
Verification Ladder
Use the cheapest check that proves the claim:
- Compile first:
typst compile main.typ main.pdf.
- For text, headings, tables, and structure, export HTML:
typst compile main.typ /dev/stdout -f html --features html 2>/dev/null.
- For counts, metadata, page numbers, and labels on Typst 0.15+, use
typst eval --in main.typ 'query(heading).len()'.
- For Typst 0.14, use
typst query main.typ "heading" or typst query main.typ "<label>".
- For layout, alignment, page breaks, headers, and fonts, export PNG:
typst compile main.typ "page-{p}.png" -f png.
- If HTML export is unavailable, fall back to
pdftotext main.pdf - for content checks.
Package And Template QA
For Typst packages or reusable templates, add only the checks that apply:
typst-package-check check .
typstyle --check lib.typ src/*.typ
tt run
typst compile template/main.typ
Skip missing optional tools gracefully. typst-package-check validates package shape, typstyle checks formatting, and tt/tytanic catches visual regressions against reference images.
Pitfalls
- Typst has markup mode and code mode. Use
# to enter code from markup, but do not put stray # inside normal code expressions.
- In math, preserve call/subscript intent with spacing:
$ E(v) $ means E applied to v.
$ E_h (v) $ means E_h applied to v.
$ E_(h(v)) $ means E with subscript h(v).
- Avoid
$ E_h(v) $ when intent is function application; it reads ambiguously as subscript/call glued together.
csv(..., row-type: dictionary) requires a header row; values are strings until converted.
- Do not import everything from broad packages with
* unless the package explicitly recommends it.
- Inside a package, root paths like
/src/core.typ resolve to the package directory, not the user's project root.
- Avoid reproducing large package features manually. Universe packages already cover diagrams, slides, theorem boxes, pseudocode, glossaries, units, CVs, tables, and many templates.
- Generated PDFs may compile while still being visually wrong. Inspect output or preview when layout matters.
- Keep custom styling restrained unless the user asked for a new visual identity; default Typst output is often a better baseline than over-designed decoration.