9 Min. Lesezeit

Typst Logo

Ich habe Typst vor ca. zwei Wochen für mich entdeckt – und bin total schockverliebt! 😍

Was ist Typst?

Typst ist ein Satzsystem und noch so viel mehr. Der eine oder die andere kennt vielleicht TeX/LaTeX noch aus Studienzeiten. Das war/ist wohl der defacto Standard fürs Verfassen wissenschaftlicher Arbeiten. Es ist mächtig, aber auch kompliziert. Es gibt unendlich viele Bücher über die Benutzung von TeX/LaTeX. Für Typst gibt es nahezu noch keine Bücher, soweit ich das sehe (Stand Dezember 2025).

Typst wurde von zwei Deutschen in Berlin erfunden, Martin Haug und Laurenz Mädje. Die Software ist OpenSource und man kann sie kostenlos benutzen.

Wie nutzt man Typst?

Da wäre zunächst einmal die Browser basierte Web App unter https://typst.app/app. Sie bietet auch ein Live Preview, so dass man direkt sieht, was man in der .typ Datei nebenan verzapft.

Ein anderer Weg ist es, sich den Typst Compiler selbst auf seinem Rechner (in meinem Falle also Macs) zu installieren. Das geht am einfachsten mal wieder über Homebrew mit

brew install typst

Jetzt kann man im Texteditor seiner Wahl z.B. die Quelldatei meindokument.typ schreiben und dann mit

typst compile meindokument.typ

daraus die zugehörige PDF Datei erzeugen.

Typst kann übrigens nicht nur nach PDF exportieren, sondern auch Grafikdateiformate erzeugen. Wenn man also z.B. nur mal eine mathematische Formel in schön als PNG Datei haben möchte, geht das. Oder – wie wir noch sehen werden – eine programmierte Illustration als SVG fürs Web? Geht auch. Man kann sogar nach Markdown exportieren, nach HTML oder nach Text. Wobei der HTML Export derzeit wohl noch in den Anfängen steckt, ich habe ihn noch nicht probiert.

Tipp VSCode

Noch schöner wird das Arbeiten aber, wenn man sowieso schon Visual Studio Code (VSCode) auf dem Rechner hat. Denn dann installiert man sich die Erweiterung Tinymist Typst und genießt eine integrierte, lokale Entwicklungsumgebung mit fast allen Schikanen & Features, von denen der Live Preview nur ein Highlight ist. Das sieht dann ungefähr so aus:

Screenshot der Arbeitsumgebung mit Typst und der VSCode Erweiterung Tinymist Typst
Screenshot der Arbeitsumgebung mit Typst und der VSCode Erweiterung Tinymist Typst

Die Erweiterung Tinymist Typst bringt ihr eigenes Typst binary mit. Wenn man sich also für dieses Setup entscheidet, muss man nicht unbedingt auch selbst über Homebrew Typst lokal installiert haben. Man muss nur wissen, dass die Typst Version, die mit dieser VSCode Erweiterung kommt, nicht immer unbedingt gleichauf mit der zuletzt veröffentlichten Version von Typst ist. Wenn Typst also in einem Update neue Features bringt, auf die man angewiesen ist bzw. die man unbedingt nutzen will, dann bedeutet dieses Szenario unter Umständen erstmal, dass man etwas Geduld haben muss, bis auch die Tinymist Erweiterung auf den neuesten Stand gebracht wurde.

Man kann zwar in den Einstellungen der Erweiterung auch einen Pfad zu seinem eigenen, lokalen Typst konfigurieren, aber gemeint ist hier nicht das Typst Binary (der Compiler) selbst, sondern Tinymist selbst. Das kann man sich nämlich auch über Homebrew installieren (brew install tinymist). Ich habe darin aber bis jetzt noch keinen Vorteil erkannt und beschränke mich im Moment fürs lokale Arbeiten an Typst Dokumenten auf die Tinymist VSCode Erweiterung.

Github

Es kann Gründe geben, dass man seine Typst Quelldateien (dazu gehören ja ggfs. auch Bilder oder Fonts) in ein Github Repository legt. So können auch andere lernen, sehen, mitverfolgen, wie man Typst Dokumente schreibt und was alles wie darin funktioniert. Sie können sich dann die Quellen herunterladen und selbst weiter experimentieren.

Oder man hat mehrere Geräte, an denen man am selben Dokument arbeiten will und möchte einfach, dass die Dokumente zentral an einem Ort im Internet/in der Cloud liegen. So kann man immer am Ende der Arbeit alles ins Repository hoch pushen und beim Wechsel an ein anderes Gerät sich zu Beginn der Arbeit einmal den letzten Stand holen/pullen. Ein Computer mit VSCode und Internetzugang genügt.

Natürlich bietet das Arbeiten mit Github vor allem dann auch die Möglichkeit, dass mehrere Menschen an ein und dem selben Dokument arbeiten können, das könnte ja z.B. auch ein Buch Projekt sein und aus vielen Dateien bestehen.

Ich habe mein bisher erstes und einziges Typst Dokument, was ich immer weiter schreibe und dabei Typst lerne, in dieses Github Repository gelegt. Falls ihr mal schauen wollt.

Ein bisschen Automatisierung

Außerdem bietet Github (oder auch andere, ähnliche Plattformen) natürlich Workflows zum Automatisieren von Aufgaben. Ich habe mir zwei Workflows eingerichtet:

Build

Ein “Build” Workflow, der immer dann zuschlägt, sobald ich eine Änderung ins Repository pushe. Dann wird der Typst Compiler auf Github (also innerhalb des Ubuntu Runners) angeworfen und erzeugt das PDF als Artifact. Damit macht der Workflow aber zunächst nichts weiter. Wenn ich das PDF brauche, kann ich es mir aus dem Ergebnis des Build Workflows bequem herunterladen:

Screenshot des Ergebnisses des Build Workflows
Screenshot des Ergebnisses des Build Workflows

Release

Das ist mein “Release” Workflow, der immer dann zuschlägt, sobald ich in VSCode ein tag vergebe und es eine neuere Version der Datei CHANGELOG.md gibt, damit ich auch brav Releasenotes pflege. Es wir dann ein neues Release mit dem vergebenen tag angelegt, welches sowohl die erzeugte PDF Datei enthält, als auch in Form einer ZIP Datei alle zum Erzeugen dieses PDFs notwendigen Quelldateien, also v.a. die .typ Dateien, aber auch die Fonts und Bilder in ihren jeweiligen Unterordnern.

Screenshot eines Releases, was der Release Workflow erstellt hat
Screenshot eines Releases, was der Release Workflow erstellt hat

Wie diese beiden Workflows, die im Repository unter .github/workflows als .yml Datei zu finden sind, gebaut sind, könnt ihr dort selbst nachschauen, denn das Repository ist ja öffentlich. Hier die Direktlinks: build-pdf.yml und release.yml.

Typst als Programmiersprache

Dazu, was in Typst alles möglich ist – vor allem dann auch mit den hunderten 3rd party Erweiterungspaketen! –, könnte man ganze Bücher schreiben. Und es gibt auch schon zahlreiche Tutorials und YouTube Videos von denen man prima lernen kann. Daher will ich in diesem Artikel gar nicht erst versuchen, eine Typst-Einführung zu geben.

Allerdings möchte ich doch einen Aspekt hervorheben: Typst ist nicht nur ein Satzsystem, in dem man ähnlich wie in Markdown oder auch wie mit LaTeX Texte/Dokumente verfassen kann. Typst ist auch Programmiersprache. Und das eröffnet natürlich große Welten! So kann man zum Beispiel Tabellen oder Grafiken direkt im Dokument dynamisch erzeugen.

Tabelle mit errechneten Zahlen

Als einfaches Beispiel schauen wir uns mal die Fibonaccizahlen an. Möchte man eine Tabelle der ersten 16 Fibonaccizahlen in sein Dokument einbauen, geht das zum Beispiel so:

// Wir definieren eine Funktion, die Fibonaccizahlen errechnen kann:
#let fib(n) = (
  if n <= 2 { 1 }
  else { fib(n - 1) + fib(n - 2) }
)

// Eine Variable für die Anzahl der Fibonaccizahlen in der Tabelle:
#let count = 16

// Eine Variable, die die Zahlen von 1 bis zu count enthält
#let nums = range(1, count + 1)

// Im Fließtext wird an der Stelle von #count der Wert der Variablen count eingesetzt:
Ein gutes Beispiel für sowohl Tabellen, als auch dass man in Typst selbst dynamisch Inhalte erzeugen kann, ist diese Tabelle mit den ersten #count Fibonaccizahlen.

// Jetzt erzeugen wir eine zentrierte Tabelle mit zwei Zeilen und count Spalten:
#align(center,
   table(
      columns: count,
      fill: (_, row) => if row == 0 { luma(230) } else { none },
      ..nums.map(n => $F_#n$),
      ..nums.map(n => text(orange)[#str(fib(n))]),
   )
)

Das Ergebnis im PDF sieht dann so aus:

Screenshot aus dem erzeugten PDF File
Screenshot aus dem erzeugten PDF File

Der Knackpunkt ist jetzt eben, dass wir lediglich den Wert der Variablen count ändern müssen, wenn wir mehr oder weniger Spalten und errechnete Fibonaccizahlen haben wollen. Wir müssen niemals selbst die Fibonaccizahlen errechnen und “hard coded” in die Tabelle eintragen! Und selbst im Begleittext darüber, wo wir “… mit den ersten 16 Fibonaccizahlen.” stehen haben, wird die Zahl dynamisch ausgetauscht, wenn wir den Wert der Variablen count ändern.

Der Informatiker wird bemerkt haben, dass auch Rekursion möglich ist, denn die Funktion fib(n), die wir uns programmiert haben, ruft sich selbst wieder auf. Natürlich kann man die Errechnung der Fibonaccizahlen auch nicht-rekursiv machen und wenn man sehr viele davon berechnen lassen will, sollte man das auch so tun. Aber für die wenigen hier im Beispiel ist Rekursion schon okay.

Komplexeres Diagramm

Eins meiner Lieblings-Mathe-Themen ist das Ding mit der $3n+1$ Zahlenfolge, auch bekannt als Collatz-Problem oder von Martin Gardner in seinem Scientific American Artikel von 1984 als Hailstone Numbers bezeichnet, weil die Zahlen wie Hagelkörner im Sturm ständig auf und ab fallen.

Wenn man in seinem Typst Dokument ein paar Funktionen programmiert, mit deren Hilfe man die Zahlenfolge hübsch visualisieren kann, lockert das den Text prima auf. Dazu dieses Beispiel, welches die Funktionen collatz_all, collatz_visualizer_horizontal und collatz_visualizer benutzt. Mit dem Typst-Quellcode

#let startzahl = 5
#let periodenlaenge = collatz_all(startzahl).len()
#figure(
   collatz_visualizer_horizontal(startzahl, scale: 1.1),
   caption: [$3n+1$ Folgenglieder für die Startzahl #startzahl mit Periodenlänge #periodenlaenge]
) <collatzdiagramm1>

erzeugen wir dynamisch im PDF dieses Diagramm (Screenshot):

Screenshot aus dem erzeugten PDF File
Screenshot aus dem erzeugten PDF File

Man beachte auch im Untertitel der Abbildung die dynamisch eingebauten Zahlen, die die Werte der Variablen startzahl und periodenlaenge sind. Sobald wir im Typst Quellcode diese Werte ändern, wird sofort eine neue, dazu passende Grafik durch die programmierten Funktionen erzeugt.

Die Funktion collatz_visualizer_horizontal stößt natürlich rein platz-technisch schnell an ihre Grenzen, da die Zahlenfolgen mit größeren Startzahlen dann auch lang werden.

Daher habe ich die generischere Funktion collatz_visualizer implementiert, die dem Rechnung trägt. Nehmen wir zum Beispiel die Startzahl 11, ergeben sich 15 Folgenglieder, das wird rein horizontal ggfs. schon etwas eng.

Mit der Funktion collatz_visualizer habe ich die Möglichkeit, die Zahlen untereinander fortlaufen zu lassen und eine maximal Anzahl von Zahlen pro Spalte anzugeben. Hier zum Beispiel sind es 5 Zahlen untereinander, ehe auf die nächste Spalte “umgebrochen” wird:

Screenshot aus dem erzeugten PDF File
Screenshot aus dem erzeugten PDF File

Wenn ich allerdings vertikalen Platz sparen will, gebe ich als zweiten Parameter statt 5 einfach 3 an und erhalte sofort diese Grafik:

Screenshot aus dem erzeugten PDF File
Screenshot aus dem erzeugten PDF File

Der Unterschied liegt lediglich am zweiten Parameter der Funktion. Hier das Aufruf-Beispiel im Typst Dokument für den zweiten Fall mit maximal 3 Zahlen untereinander:

#let startzahl = 11
#let diagrammZeilen = 3
#let periodenlaenge = collatz_all(startzahl).len()
#figure(
   collatz_visualizer(startzahl, diagrammZeilen, scale: 1.0),
   caption: [$3n+1$ Folgenglieder für die Startzahl #startzahl mit Periodenlänge #periodenlaenge]
) <collatzdiagramm2>

Man beachte den dritten Parameter der Funktion collatz_visualizer, den Skalierungswert.

Denn berüchtigt und bekannt ist die zunächst harmlos aussehende Startzahl 27. Bei ihr entstehen allerdings 112 Folgenglieder und dann können wir das gesamte Diagramm herunterskalieren, damit es – hier mit 10 Zahlen pro Spalte – noch auf die Seite passt:

Screenshot aus dem erzeugten PDF File
Screenshot aus dem erzeugten PDF File

Der Vollständigkeit halber dazu noch der Aufruf im Typst Dokument:

#let startzahl = 27
#let diagrammZeilen = 10
#let periodenlaenge = collatz_all(startzahl).len()
#figure(
   collatz_visualizer(startzahl, diagrammZeilen, scale: 0.6),
   caption: [$3n+1$ Folgenglieder für die Startzahl #startzahl mit Periodenlänge #periodenlaenge]
) <collatzdiagramm3>

Die Implementierungen der für diese Grafiken notwendigen Funktionen füge ich hier nicht ein, da sie etwas umfangreich sind. Aber auch hier gilt wieder: Mein Repository ist öffentlich, man kann sich die Programmierung (bei der übrigens die K.I. Google Gemini in beeindruckender Weise geholfen hat) dort anschauen. Derzeit sind die Funktionen noch in der Hauptdatei typst-demo-stefan-1.typ enthalten, das mag sich aber ändern, wenn ich sie noch in meine Bibliotheksdatei _lib.typ auslagern sollte.

Fazit

Ihr seht, die Möglichkeiten sind schier grenzenlos. Da könnte man jetzt zig Beispiele bringen. Schaut einfach gerne ab und zu in mein Demo-Dokument in meinem Repository rein, was ich in den kommenden Tagen/Wochen/Monaten sicher immer weiter ausbauen werde.

Ich bin begeistert von Typst und unterstütze das OpenSource Projekt seit kurzem auch finanziell auf Github als (bescheidener) Sponsor.

Vielleicht konnte ich euch ja anstecken mit meiner Begeisterung und ihr probiert Typst auch mal aus oder entscheidet euch sogar auch, das Projekt zu sponsern. Jeder Betrag hilft!

🔲

Hinterlasse einen Kommentar