Typst Guide

Typst Counters

Built-in counters for pages, headings, figures, tables, equations. Custom counters for anything else. Access with #counter(...).

Built-in counters

CounterTracks
#counter(page)Current page number
#counter(heading)Heading numbering
#counter(figure)Figure numbering
#counter(figure.where(kind: table))Table numbering
#counter(math.equation)Equation numbering
#counter(footnote)Footnote numbering

Display the current page number

// In a footer
#set page(
  footer: align(center)[
    Page #counter(page).display()
  ],
)

// As Roman numerals
#counter(page).display("I")        // I, II, III

// As letters
#counter(page).display("A")        // A, B, C

"Page X of Y" footer

#set page(
  footer: context align(center)[
    Page #counter(page).display() of #counter(page).final().at(0)
  ],
)

Note the context — needed because final() requires evaluation context.

Reset / change page numbering

// Front matter: Roman numerals starting from i
#set page(numbering: "i")
#counter(page).update(1)

... title page, TOC, abstract ...

// Main matter: Arabic numerals starting from 1
#set page(numbering: "1")
#counter(page).update(1)

... chapters ...

Custom counter

#let definition-counter = counter("definition")

#let definition(body) = {
  definition-counter.step()
  block(stroke: 0.5pt, inset: 8pt)[
    *Definition #context definition-counter.display():*
    #body
  ]
}

#definition[A natural number is...]   // Definition 1
#definition[A prime number is...]     // Definition 2

Reset figure counter at appendix

// In appendix section
#counter(figure).update(0)
#counter(heading).update(0)
#set heading(numbering: "A.1")    // appendix-style numbering

= First Appendix Section          // A.
#figure(image("..."), caption: [...])    // Figure A.1
#figure(image("..."), caption: [...])    // Figure A.2
Try Typst counters live

TypeTeX is a free in-browser Typst editor — experiment with counters and see updates instantly.

Try TypeTeX free

Frequently Asked Questions

What's a counter in Typst?

A counter is a number that increments automatically as you write — like LaTeX's counters. Built-in counters track pages, headings, figures, tables, equations, and footnotes. You can also create custom counters for chapters, definitions, exercises, etc. Access them via the #counter() function.

How do I get the current page number?

#counter(page).display() returns the current page number. Often used in headers/footers: #set page(footer: align(center)[#counter(page).display()]). The .display() converts the internal number to displayable content.

How do I reset a counter?

#counter(page).update(0) sets the page counter to 0 (so the next page is 1). #counter(figure).update(0) restarts figure numbering. Often used at the start of a new section: appendix figures restart at A.1, etc.

How do I increment a counter manually?

#counter("my-counter").step() increments by 1. .update(n => n + 5) for arbitrary updates with a function. Most users don't need this — built-in counters auto-increment from headings, figures, etc.

How do I create a custom counter?

#let mycount = counter("mycount"). Then #mycount.step() to increment and #mycount.display() to show. Useful for: definition counters in math papers, exercise counters in textbooks, custom labeled blocks.

How do I display a counter as Roman numerals?

Pass a numbering pattern: #counter(page).display("I") for I, II, III. Other patterns: "i" for lowercase Roman, "a" for letters, "A" for uppercase letters, "1" for default Arabic. Used in front matter pagination (Roman pages before main matter).

How do I get 'page X of Y' in a footer?

#counter(page).display() of #counter(page).final().at(0). The .final() returns the final value (the last page in the document). Combine: 'Page 3 of 12'. Common pattern in thesis footers.

How do I display a heading counter in a custom format?

#counter(heading).display() returns the current heading number. To show only level 1: #counter(heading).at(here()).first() — or use specific accessor methods. Most users just rely on heading numbering directly via #set heading(numbering: ...).

Can I show the count of figures so far?

Yes: #context counter(figure).get().first() returns the current figure number. The #context block evaluates lazily — necessary for counters because they're location-dependent. Without #context, the value is 'unknown' at the time of compilation.

More Typst guides