Alongside our public beta launch, we're shipping a big update for Typst. This update is all about making Typst ready for real research work. You can now add bibliographies and cite from them, cross-reference your sections, figures, and equations. These new features are backed by powerful primitives that you can use to build your own abstractions.

It's been a while since the last big update for Typst. But we've been hard at work and this update is all the more packed with features. But first a quick interruption: This update coincides with our public beta launch! Be sure to read the announcement blog post first.

Bibliography and references

Typst now has built-in bibliography management. You can either bring a BibTeX file or make use of Typst's native bibliography file format, Hayagriva. Add a bibliography with the bibliography function and @cite from it with the reference syntax. The same syntax can also be used to insert cross-references to sections, equations, and other things that have a <label> attached to them.

#set heading(numbering: "1.")
#set math.equation(numbering: "(1)")

= Introduction <intro>
Recent developments in
typesetting software have
rekindled hope in previously
frustrated researchers. @distress
As shown in @results, we ...

= Results <results>
We discuss our approach in
comparison with others.

== Performance <perf>
@slow demonstrates what slow
software looks like.
$ O(n) = 2^n $ <slow>

#bibliography("works.bib")
Preview

The built-in bibliography management, numbering and cross-referencing works out of the box with zero setup. But it wouldn't be in the spirit of Typst to stop there. Everything you've seen above, you can also build yourself with new low-level primitives.

Do It Yourself

With new counter function, you can inspect and modify the counters of pages, headings, figures, and create custom ones. Maybe your document contains a bunch of theorems that you want to count through? The counter function ensures that the theorems are numbered exactly in the order of the final layout, no matter how you organize them in the markup.

#let c = counter("theorem")
#let theorem(body) = [
  #set par(hanging-indent: 10pt)
  *Theorem #context c.display().*
  #body
  #c.step()
]

#theorem[
  The square of any real number is
  non-negative.
]

#theorem[
  The sum $1 + ... + n$ is:
  $ sum_(k=1)^n k = (n(n+1))/2 $
]
Preview

Aside from counters, you might want to manage other state across your document. The new state has got you covered.

A particularly cool addition is the query function. This function lets search for elements in your document. You can use it to build a custom list of figures or to create a page header that displays the current chapter title.

The example below demonstrates what queries can do: We first call the locate function to determine the location of itself within the document. We then query for all headings after that location. The result is an array with all matching elements. Since the "Introduction" heading is before the locate call and we queried for headings after the location, this prints "Upcoming: Background and Analysis."

= Introduction
#context {
  let upcoming = query(
    selector(heading).after(here()),
  )
  [Upcoming: ]
  upcoming
    .map(it => it.body)
    .join[ and ]
}.

= Background
#lorem(10)

= Analysis
#lorem(10)
Preview

The new measure function lets you find out the layouted size of some content. That's super useful for building flexible layouts that react to what's given to them.

#style(styles => {
  let content = [Hello]
  let size = measure(content, styles)
  [#content has width #size.width]
})
Preview

If you've previously dealt with content values in Typst, you might be familiar with these four letters: [..]. Previously, content was really opaque in Typst and you couldn't really do much it with except put it somewhere in your layout. This ends today. With the new update, you can have a look at what's inside of content values, compare them, and traverse them with code.

People have already built some cool libraries in Typst during the preview test. But they have been limited by the lack of lower level primitives for state handling and content manipulation. We hope that the additions in today's update make it easier to create packages and abstractions from which the whole community can benefit.

Web App Improvements

We've not only been busy with the Typst langauge and compiler. The web has also gotten some long-awaited upgrades.

The new jump-to-source feature lets you click on anything in the preview panel and brings you straight to the exact piece of source code that produced it. It works for text, images, shapes, and even inside of equations!

Alongside the template creator, the web app now has a template gallery. It ships with five pre-made templates that you can use for your documents. That's just the start though: More templates will be added over time and we also plan to integrate the gallery with the upcoming package manager.

When editing a document, it's often the small things that matter: We've added a few new editor buttons to the app, so that you can insert headings, equations, code blocks and references more easily. Furthermore, we've improved the hover tooltips so that they work properly for multi-file setups and in show rules.

The Typst app ships with a selection of fonts that cover a wide range of use cases. But something you just want that one particular font. You can now upload your own fonts into the web app. There's even a little preview if you click on them in the file panel.

That's it for this update! Visit the changelog for a comprehensive overview of all changes. And if you like where Typst is going, be sure to share it with your friends and colleagues!