How to format tables in Typst

Make a table in Typst with the #table function: set columns to the number of columns (or a list of widths), then list the cells in reading order. Use table.header for a repeating header, table.cell(colspan: n) to merge cells, and stroke: none to remove the lines.

Typst fills the grid row by row, so you write cells in the order you read them — there is no & separator and no row terminator.

#table(
  columns: 3,
  table.header[Method][Acc.][Time],
  [Baseline], [0.81], [12s],
  [Ours],     [0.94], [3s],
)
A three-column Typst table with a Method, Acc. and Time header row and two data rows.

A complete document you can paste

Everything below is a working file — save it as main.typ and compile.

#set page(paper: "a4", margin: 2.5cm)
#set text(size: 11pt)

= Results

#figure(
  table(
    columns: (auto, 1fr, 1fr),
    stroke: none,
    align: (left, center, center),
    table.hline(),
    table.header[Method][Accuracy][Time],
    table.hline(stroke: 0.5pt),
    [Baseline], [0.81], [12s],
    [Ours],     [0.94], [3s],
    table.hline(),
  ),
  caption: [Accuracy and runtime.],
) <tab:results>

As @tab:results shows, the method is both faster and more accurate.
An A4 page with a stroke-free results table using horizontal rules only, captioned 'Accuracy and runtime.', and a sentence referring to Table 1.

Column widths and alignment

columns takes a count or a list of track sizes: auto fits the content, 1fr takes a share of the remaining space, and a length like 3cm is fixed. align takes one value for the whole table or one per column.

#table(
  columns: (auto, 1fr, 3cm),
  align: (left, center, right),
  [Name], [Description], [Value],
)
A table whose first column sizes to content, second column absorbs the free space, and third column is fixed at 3 centimetres.

Merging cells

table.cell with colspan or rowspan merges cells. You do not leave gaps for the covered area — Typst flows the following cells around it.

#table(
  columns: 3,
  table.cell(colspan: 2)[Merged across two columns], [C],
  table.cell(rowspan: 2)[Tall], [b1], [c1],
  [b2], [c2],
)
A table with one cell merged across two columns and another cell spanning two rows.

Styling a single column

A show rule targeting a cell position styles a whole column at once — x is the zero-based column index, y the row.

#show table.cell.where(x: 0): strong
#show table.cell.where(y: 0): set text(size: 9pt)

#table(
  columns: 3,
  [Method], [Acc.], [Time],
  [Baseline], [0.81], [12s],
)
A table where every first-column cell is bold and the header row is set in a smaller size, applied by show rules.

Rules, padding, and text size

stroke: none removes every line; add table.hline() for the horizontal-rules-only look journals expect. inset sets the padding inside cells, and a #set text rule around the table changes its type size.

#[
  #set text(size: 9pt)
  #table(
    columns: 2,
    stroke: none,
    inset: (x: 8pt, y: 4pt),
    table.hline(),
    [Left], [Right],
    table.hline(),
  )
]
A compact two-column table with wider horizontal padding, rules top and bottom only, set at 9 point.

The full argument list is in the Typst table reference.

In KL studiothe preview recompiles as you tweak columns, align, or a show rule, so you see the layout change immediately instead of waiting on a full rebuild.

Common questions

How do I merge columns in a Typst table?
Wrap the cell in table.cell(colspan: n)[...] to span n columns, or table.cell(rowspan: n)[...] to span rows. Typst lays the remaining cells out around it, so you do not add placeholder cells for the space it covers.
How do I make one column bold in a Typst table?
Pass a function to the table's align or use a show rule, but the simplest way is to set the whole column with table.cell: give the cells you want bold a strong[...] body, or add #show table.cell.where(x: 1): strong to make column index 1 bold everywhere in that table.
How do I remove the lines from a Typst table?
Set stroke: none on the table. To keep only horizontal rules (the booktabs look), leave stroke: none and add table.hline() where you want a line.
How do I decrease the text size in a Typst table?
Wrap the table in a block that sets the text size: #[#set text(size: 9pt); #table(...)]. The set rule applies to everything inside, including the header.
How do I repeat the header on every page of a long Typst table?
Put the header cells in table.header(...). Typst repeats it automatically when the table breaks across pages; pass repeat: false to turn that off.
How do I set the row height in a Typst table?
Use the rows argument: table(columns: 3, rows: 2em, ...) sets every row, and rows: (auto, 3em) sets them individually. inset controls the padding inside each cell.