My Experience with Typst So Far
I’ve been trying Typst in my work for some time. For those of you who don’t know, Typst is a new language/tool for typsetting technical documents. Its goal is to be a better alternative to (La)TeX, which as probably everyone in the academia would agree, has not been pleasant to use. Different people might have different problems with LaTeX. For me, it’s mostly the gibberish error messages (such as “Undefined control sequence” followed by some weird string I’ve never seen), confusing package compatibility (some package for some reason can’t be used together with a package in the dependencies of acmart?), difficult-to-access documentation (why are packages documented in a book-like PDF files?), and bad tooling (maybe because of this). Based on my experience so far with Typst, it does fix those problems pretty well.
The Language
Core to what makes everything suddenly so much nicer in Typst is the language itself. You can treat it as if you were dealing with something as simple as Markdown, but all those things you see are just syntax sugar. Under the hood it is a proper Turing-complete programming language. Two nice things I have noticed about the language so far:
- Typed. It is handling actual data of specific types that can’t be mixed up. Compare that with (La)TeX where with the exception of primitives it’s all just pattern matching on text and macro expansions (TeX has character codes but those are token-level and only used to guide parsing).
- Purely functional. This means
- We can tweak whatever settings in a
context like a paragraph without worrying about
it conflicting with anything outside, because
it has no side effects when viewed from outside.
For example, I can define a bunch of functions
in my template library tweaking the styles in
all kinds of crazy ways, but a user doesn’t
need to worry about it affecting things that
are not output from those functions. If I have a document A
and need to create a second document B that needs to
reuse some content from A, I can simply bind that
content to a name through
let
,import
A and reference it in B. I don’t need to worry about messing up B’s formatting with A’s. - We can memoise the results due to referential transparency. My understanding is that this is the main enabler of incremental compilation in Typst. I’m using Typst with the “Typst Preview” VSCode extension, and it can update the rendered file instantaneously when I type. This makes up a lot for not being WYSIWYG like Word.
- We can tweak whatever settings in a
context like a paragraph without worrying about
it conflicting with anything outside, because
it has no side effects when viewed from outside.
For example, I can define a bunch of functions
in my template library tweaking the styles in
all kinds of crazy ways, but a user doesn’t
need to worry about it affecting things that
are not output from those functions. If I have a document A
and need to create a second document B that needs to
reuse some content from A, I can simply bind that
content to a name through
Bells and whistles
The show
rule is just like CSS rules which allow the user to set
attributes for elements selected by selectors. I find it a convenient
way to quickly highlight specific keywords. Since regex is allowed in
selectors this can also be a quick and dirty
way to provide basic syntax highlighting for
code blocks.
The “Typst Preview” extension also supports jumping between the render output and the source file (similar to what SyncTeX does) which I find very convenient.
Limitations
I think Typst has the ambition to dethrone LaTeX so
in the end it would need to support whatever LaTeX currently supports.
Most things are quite clean with the language design discussed above,
but it seems that there are places where the language design can make
it harder to do things. One example I have encountered is with
the double-column layout. It is quite common that in a double-column
document, one needs to make a few selected elements (e.g., a
table or a figure) span the whole
page width. As far as I know, this is not currently possible with Typst.
Perhaps this is fundamentally tricky given the purely functional language
design.
For example, right now if we put some content in a columns(2)
environment,
that content is just going to split into a two columns. If another columns(3)
is nested inside it, each of the two columns is going to be split
further into three columns. Now, if inside columns(3)
we want to have
a wide table, should that table span a column of the outer columns(2)
environment, or the full page width?
It’s unclear how to decide between the two options without knowledge about
the outside context.
Moreover, now something inside columns(3)
could have global side-effects
(disrupting the whole page layout).
Documentation
The documentation of the standard library is available as searchable web pages, and they have
planned to set up a central documentation hosting platform like docs.rs
too.
Presentation
I created presentation slides with Polylux (there are other packages
for slides but they look the same so I just pick one that seems most
popular). For basic animations that just involve
hiding and unhiding things, it’s already quite usable.
However, animations that require changing attributes are a bit tricky
and the current way to do this is to basically pass the different
versions in alternatives
. Defining a function to output both (selected
by the function argument) saves some copy-pasting but even for very
simple tasks it still requires cluttering the document with
one-off boilerplate-like functions.
Conclusion
Right now Typst still has some limitations in terms of the functionality. It also lacks support from major journals and conferences. Those problems are holding me back from using Typst for writing papers. However, I’m happy to use it as much as I can for less complex tasks and personal notes while waiting for Typst to mature more. I have little doubt that Typst will become widely adopted to the point that publication venues start providing official support, and that will probably be soon.