synkit is a Typst package for drawing syntax trees from bracket notation. It focuses on fast authoring, clean output, and the kinds of features syntacticians and semanticists actually need in day-to-day work.
Philosophy
There are two key design choices for this package. First, the syntax should be minimal, intuitive, and readable. As a result, a tree is separated from its add-ons (arrows, highlights, etc.) inside the #tree() function. Second, functions should be smart enough to detect patterns, which helps minimize the amount of code you have to type. These two points are clearly connected to each other.
Here are some examples illustrating this philosophy.
- Labels are automatically created. Every word or node you add to a tree automatically becomes a label that can later be targeted by an arrow, an annotation, or by an aesthetic adjustment (color, highlight, etc.).
- Triangles are automatically added to trees.
[XP content]will trigger a triangle, but[XP [X' [X content ] ] ]will not. So, while you can add triangles manually, you will likely never have to do that. - Terminal branches aren’t displayed by default (e.g., no line/link between a terminal node and its content
[X content]). You can activate them if you so choose, but by default they won’t be there. - When you define a tree, spaces don’t matter so much:
[NP[Det][N]]is the same as[NP [Det ] [N] ]or any other equivalent string. Thus, you will no longer get syntax errors if you forget a space between two]](cf.tikz-qtreein LaTeX).
Some examples
Installation
#import "@preview/synkit:0.0.1": *
If you are working from a local clone instead, import lib.typ directly:
#import "synkit/lib.typ": *
Highlights
- Draw syntax trees with flexible bracket notation using
#tree() - Add movement arrows, curved paths, delinking, and trace targeting
- Don’t worry about creating triangles manually: they are automatically added based on phrase structure
- Add multidominance and cross-tree equivalence lines between two trees using
#garden() - Add semantic annotation between node labels and branches
- Create numbered examples with
#eg()and interlinear glosses with#gloss() - Adjust spacing, direction, scale, highlighting, numbering, and colors with lightweight arguments
- Smart labels ensure that you never have to create labels yourself: every word, node and even emoji is its own label
Manual
See the manual for a comprehensive description of each function available. Check synkit.pdf in the GitHub repository.
Repository
Author
Guilherme D. Garcia
Email: guilherme.garcia@lli.ulaval.ca
Website: https://gdgarcia.ca
License
MIT





