Typst Guide

Typst Conditionals & Loops

#if, #else, #for, #while. Control flow that lets you compute, iterate, and conditionally include content.

Conditionals

#let score = 0.85

// Inline
The model is #if score > 0.7 [accurate] else [inaccurate].

// Block form
#if score > 0.9 [
  Excellent performance.
] else if score > 0.7 [
  Good performance.
] else if score > 0.5 [
  Acceptable performance.
] else [
  Poor performance.
]

// Code-block style (for computation)
#let category = if score > 0.7 { "good" } else { "bad" }

For loops

// Iterate over an array
#let methods = ("Random", "Linear", "Neural")
- #for method in methods [#method, ]

// With index
#for (i, method) in methods.enumerate() [
  #(i + 1). #method \
]

// Range
#for i in range(1, 6) [
  Item #i \
]

// Iterate over dictionary
#let scores = (
  random: 0.5,
  linear: 0.7,
  neural: 0.92,
)
#for (name, score) in scores.pairs() [
  #name: #score \
]

While loops

#let n = 1
#while n < 1000 {
  // Compute something
  n = n * 2
}

Less common than #for in document construction. Useful for accumulator-driven logic or numeric algorithms.

Switchable document modes

#let mode = "thesis"     // "thesis" or "paper"

= Introduction

This is the introduction.

#if mode == "thesis" [
  // Full thesis: include extended methodology
  == Extended Methodology

  This section only appears in the thesis version,
  with full derivations and additional context.
]

= Results

Main results here.

#if mode == "thesis" [
  // Include appendices only in thesis mode
  #include "appendices/proofs.typ"
  #include "appendices/data.typ"
]

Toggle mode to compile two outputs (paper vs thesis) from one source.

Generate a table from data

#let results = (
  ("Random", 0.50, 12.3),
  ("Linear", 0.71, 5.8),
  ("Neural", 0.92, 1.2),
)

#table(
  columns: 3,
  table.header([Method], [Accuracy], [Time (s)]),
  ..for row in results {
    (row.at(0), str(row.at(1)), str(row.at(2)))
  }
)

The .. spread operator flattens the loop's output into table arguments. Each row contributes 3 cells.

Common mistakes

  • Mixing {} and [] incorrectly. {} is code, [] is content. #if x { [content] } works; so does #if x [content].
  • No # on inline if. Mid-sentence conditionals need #: "The result is #if x [yes] else [no]."
  • Comparing strings with ==. Works fine in Typst: if mode == "thesis".
  • Forgetting else if syntax. Use else if condition [content], not elseif (no space).
Try Typst control flow live

TypeTeX is a free in-browser Typst editor — write a loop, see results in milliseconds.

Try TypeTeX free

Frequently Asked Questions

How do I write an if-else in Typst?

#if condition [content if true] else [content if false]. Or with code blocks: #if x > 0 { [positive] } else { [negative] }. The brackets [] denote content, the braces {} denote code. For chains: #if x > 0 [positive] else if x < 0 [negative] else [zero].

How do I loop over an array?

#for item in array [#item, ]. The body in brackets is content, evaluated once per item. Iterate with index: #for (i, item) in array.enumerate() [#i: #item]. The .enumerate() method gives index-value tuples.

How do I loop a fixed number of times?

#for i in range(0, 10) [#i ]. range(start, end) produces 0..end-1. range(start, end, step) for custom step. Or for ten of the same: #for _ in range(10) [content]. Useful for repeating layouts or generating numbered items programmatically.

Can I use conditionals inline with text?

Yes: 'The result is #if score > 0.5 [positive] else [negative].' Inline conditional content. Whitespace around the #if matters — use as needed for the surrounding sentence flow.

How do I iterate over dictionary entries?

#for (key, value) in dict.pairs() [#key: #value]. .pairs() returns an array of (key, value) tuples. .keys() returns just keys, .values() just values. Useful for generating tables from structured data.

How do I build conditional document modes (thesis vs paper)?

Define a mode variable: #let mode = "thesis". Then conditionally include content: #if mode == "thesis" [#include "appendices/full-proofs.typ"]. Lets you compile two outputs (one short paper, one full thesis) from the same source by toggling one variable.

What's the difference between {} and [] in conditionals?

{} is a code block — multiple statements, returns the last expression. [] is a content block — markdown-style content. Inside #if: [content] is shorthand for { [content] }. Use {} when you need multiple operations; use [] when you just want content.

How do I do early-exit / break in a loop?

Use the break keyword: #for x in items { if condition { break }; ... }. continue skips to the next iteration. Most Typst code is functional-style (mapping, filtering with .filter() and .map()), but break/continue work for imperative loops.

Can I generate a table from data with a loop?

Yes: #table(columns: 2, ..for row in data { (row.name, row.value) }). The .. is the spread operator — flattens the loop's array into table arguments. Handy for tables with dozens of rows from a CSV-like source.

More Typst guides