Typst Tables
One function: table(). Pass columns, alignment, and content. Wrap in figure() for caption and numbering.
Basic table
#table(
columns: 3,
[Method], [Accuracy], [Latency],
[Baseline], [75.2], [12.3 ms],
[Ours], [91.4], [ 8.7 ms],
)With alignment, header, and caption
#figure(
table(
columns: (auto, auto, auto),
align: (left, right, right),
table.header([Method], [Accuracy], [Latency]),
[Baseline], [75.2], [12.3 ms],
[Ours], [91.4], [ 8.7 ms],
),
caption: [Performance comparison.],
kind: table,
) <results>
See @results for the comparison.Column sizing options
| Spec | Effect |
|---|---|
| columns: 3 | 3 equal columns |
| columns: (1fr, 2fr) | Second column twice as wide |
| columns: (auto, auto) | Fit content, no stretching |
| columns: (5cm, 3cm) | Fixed centimeter widths |
| columns: (auto, 1fr) | First fits, second fills |
Booktabs-style rules
#figure(
table(
columns: 3,
stroke: none,
table.hline(stroke: 0.7pt),
table.header([Method], [Score], [Time]),
table.hline(stroke: 0.4pt),
[A], [1], [10],
[B], [2], [20],
table.hline(stroke: 0.7pt),
),
caption: [Booktabs-style table.]
)Layout (not data) with grid()
#grid(
columns: (1fr, 1fr),
column-gutter: 1em,
image("first.png"),
image("second.png"),
)Use grid() when you want layout without table styling — side-by-side images, multi-column text blocks, etc.
TypeTeX is a free in-browser Typst editor — type a table, see it render in milliseconds.
Start writing in TypstFrequently Asked Questions
Use the table() function: #table(columns: 3, [A], [B], [C], [1], [2], [3]). The 'columns: 3' tells Typst how many columns; cells are passed as content blocks in row-major order. Wrap in figure() for caption + numbering.
Pass an align array: #table(columns: 3, align: (left, center, right), [Method], [Score], [Time], ...). Each entry sets the alignment for one column. Use 'horizon' for vertical centering. You can also use a function: align: (col, row) => if col == 0 { left } else { right }.
table() is for data — has default rules, header styling, and integrates with figure() for captions. grid() is for layout — no rules by default, used for positioning content (like side-by-side images). Use table() for data; use grid() for arbitrary layout.
Wrap in figure(): #figure(table(...), caption: [Your caption], kind: table). The 'kind: table' tells Typst it's a table for numbering purposes (Table 1, Table 2). Reference with @label syntax after attaching <label>.
Pass stroke options: #table(stroke: 0.5pt + black, ...) for all cells, or stroke: (x, y) => ... for per-cell control. For the booktabs look (top/middle/bottom rules only), set stroke: none and use table.hline at the right rows.
Use table.header(): #table(columns: 3, table.header([Method], [Score], [Time]), [A], [1], [2], ...). Header rows render bold by default and repeat across pages for long tables. Style further with #set table.header(...).
columns can be: an integer (equal-width); an array of widths like (1fr, 2fr, 1fr) for relative; or fixed (5cm, 3cm, auto) for absolute. 'auto' fits content, 'Nfr' takes a fraction of remaining space, 'Ncm' is fixed.
Typst is dramatically simpler. No \begin/\end environments, no \hline juggling, no booktabs package import. table() is one function call with named arguments for everything (columns, alignment, stroke, fill). The biggest win: you can compute table content programmatically inside the call.