Benjamin Hackl

A Tale about Typesetting with Typst vs. TeX

Date: July 12, 2024
Tags: typesetting, teaching, typst, software

For any of the following to actually make sense, I’ll need to make a confession first. Not in the “dark secret” sort of category – actually, it probably isn’t even particularly surprising, and I even know quite a lot of colleagues that feel in a similar way.

So, here it goes: I consider myself to be a (La)TeX-aficionado; generally I’m really into typesetting – and I have been for, at this point, pretty much for the majority of my life. (I’m actually just a little and not *that* old, so this statement is perhaps not as strong as I’d like it to be. Does ~15 years already qualify as “decades”?)

Well, whatever. Now, I don’t really mean that I know and understand the inner workings of TeX down to its inner core, I haven’t even written any CTAN-distributed LaTeX packages (nor do I maintain any); just a bunch of local-ish templates for theses and some others for slides, letters, CVs, name tags, lecture notes, and articles; pretty standard stuff. I’d rather say I’m more of a enthusiastic power-user if you will; someone who would watch (and chuckle at) the “earthshaking” announcement of Don Knuth’s TeX successor at the 2010 TeX user group meeting, for example.

It is from this perspective that I say: if anyone had told me like a year or two ago that there will come a time where I’ll use anything other than LaTeX to typeset (PDF) documents involving formulas, I’d have probably laughed it off and/or declared them insane. While the situation doesn’t quite compare, I always felt like I already compromise enough if I embed typeset math on webpages using MathJax or KaTeX, I had little to no interest when it comes to actually trying to replace LaTeX from my day-to-day business.

And yet, here we are. The semester is over, my (german) discrete math lecture has ended, and I am sitting in front of my screen, staring at my 77 page long lecture notes that were typed without a single backslash (okay, thats a lie: there are still like 40 \ distributed throughout the source files). And while I still see a bunch of improvements that I could make manually, I’m actually quite happy with the typesetting.

Screenshot of Lecture Notes: title page Screenshot of Lecture Notes: graphs

All thanks to Typst!

Typst is a modern typesetting system that significantly leans into the syntax of Markdown. Internally, the Typst compiler is implemented in Rust (and open-sourced, under an Apache-2.0 license). The Overleaf-esque web platform has a freemium monetization scheme. The project, started in 2019 from two Berlin graduates, is otherwise also funded by donations.

I should perhaps also mention, for me it certainly was not a love at first sight sort of situation when it comes to Typst. I’ve ran into it a while ago already (it was mentioned in a feature request over at Manim, as an alternative to typesetting formulas using the MathTex class) – and while I did some experiments with it, of course, I initially failed to see its benefits. I also did not enjoy the idea of having to relearn how to write formulas; it took me a second and maybe even a third attempt until I actually gave it a fair try. By now, I don’t mind writing Cauchy’s integral formula instead of

\[ f(z) = \frac{1}{2 \pi i} \oint_{\gamma} \frac{f(w)}{w - z}~dw \]

as

$ f(z) = 1/(2 pi i) integral.cont_(gamma) f(w) / (w - z) thin dif w $

No, on the contrary, I really warmed up to Typst’s math syntax.

If you’d like to learn more about Typst, just take a look at their tutorials and the excellent reference manual. And in particular, if you are – like me – coming from a LaTeX world, they do have a dedicated page where a gentle introduction featuring direct comparisons between Typst and LaTeX can be found. I won’t go into details of the language, at least not too much, but I do want to outline a few things that I particularly enjoyed, as well as some as of yet still missing features that require workarounds. Here we go, in no particular order:

  • The typesetting speed, and general feeling of “seeing” your live edits. I’ve typeset a whole bunch of lecture notes at this point, and for each of them there always has been a point (often quite soon, after like 30 to 40 pages) where I felt the compilation speed to be simply excruciatingly slow; in particular for long files with lots of figures.

    My discrete math lecture notes are 77 pages long, with over 70 (programmatically) drawn graphs and figures. The initial compile time with typst is 7.8s, after which changes are typeset in ~200ms. I can’t stress how nice the feeling of this sort of immediate feedback is. On top of this, the error messages thrown by Typst are really great and helpful (at least the core library; this degrades somewhat in the context of plugins and external packages).

  • The way how Typst’s math mode is set up makes it impossible to run into one of my pet peeves when it comes to typesetting formulas with LaTeX: not using math operators, for example by writing sin instead of \sin. Typst’s math mode forces you to set everything up based on (predefined, or self-defined) variables and identifiers: sin refers to the predefined sin-operator, if you wanted to typeset the product of variables s, i, and n, you would need to write it as s i n.

    Practically, this requires some getting used to, but I find

    #let Res = op("Res")
    $Res(f(z), z=z_0)$
    

    isn’t much different from

    \DeclareMathOperator{\Res}{Res}
    $\Res(f(z), z=z_0)$
    

    anyways. With the difference that without the explicit definition of Res in Typst, $Res(f(z), z=z_0)$ would error out.

    Similarly, and that took even more getting used to: fractions in Typst are written as plain inline fractions using /, they are typeset automatically; no need for any sort of \frac{...}{...}-like construction.

  • I also find the “code mode” of Typst pretty sane with readable syntax – I’m not afraid to make heavy use of control structures, loops, and programmatic calculations, which definitely is a contrast to TeX. More than once I’ve resorted to writing short Python scripts that generate a bunch of LaTeX code for me; in Typst I sort of feel that I could produce maintainable solutions while mostly staying within the language itself. The example in their README also does a pretty good job at conveying this exact idea, in my opinion.

    Screenshot of Lecture Notes: Hockey Stick Theorem

    Just as a random additional example: the illustration of the Hockey Stick Theorem in the image above is realized by the following short snippet:

    #cetz.canvas(length: 0.6cm, {
      import cetz.draw: *
      for nn in range(0, 9) {
        for kk in range(0, nn+1) {
          content((2*kk - nn, -nn), [#calc.binom(nn, kk)])
        }
      }
      on-layer(-1, {
        set-style(stroke: (thickness: 15pt, cap: "round", join: "round"))
        line((2, -2), (-3, -7), (-2, -8), stroke: (paint: rgb(100%, 0%, 0%, 25%)))
        line((-1, -1), (5, -7), (4, -8), stroke: (paint: rgb(0%, 100%, 0%, 25%)))
        line((0, 0), (-6, -6), (-5, -7), stroke: (paint: rgb(100%, 0%, 100%, 25%)))
        line((4, -4), (1, -7), (2, -8), stroke: (paint: rgb(100%, 100%, 0%, 25%)))
      })
    })
    
  • One rather workflow-specific point, but I’ll include it anyways as it is part of the framework’s infrastructure: the language server coming with Typst’s VS Code extension is very good (I just wish references would work across multiple files; maybe I’ve just been using it wrong?) – actually, the extension even ships including the compiler (which is, for a fully local setup, probably the fastest way to get started at the moment). But it is not like installing the compiler manually is much more difficult; all it requires is a working Rust environment and running cargo install --locked typst-cli. (There are more options other than this manual approach, also involving package managers.)

  • And finally, through the lens of a Manim maintainer’s eye: native export to SVG feels better than latex + dvisvgm combination, plus support for data that can be attached to exported SVG paths to make them more compatible with animation frameworks is planned.

As mentioned above, there were also a few (although minor) pain points that required workarounds or deviations from my usual workflow.

  • Letting text flow around an image is a non-trivial problem and currently only works with limitations. (There are technical reasons concerning the layout model for this, an interesting blog post explaining the situation can be found here.)
  • PDF or EPS files as graphics are not currently supported in Typst – they need to be converted to SVGs first. (Which, to be fair, is only a minor inconvenience.)
  • The page breaks are sometimes a little weird (but honestly, I’d probably rather pin this on myself rather than on the language – nobody forced me to use non-breakable definition environments…).

It will probably be a while until I’ll collaborate with colleagues on a submission using Typst (and also arXiv apparently has no plans to support Typst anytime soon), but given the positive experience I’ve had this semester, I can definitely see myself working on more “single authored” Typst projects like thesis topic descriptions, Instagram postings, exams and (in case they are curious) student theses – and, well, of course also lecture notes. #emoji.face.smile