Typst: Designing for Incrementality

Lobsters Hottest Products

Summary

Typst uses constrained memoization (comemo) and pure function design to make the language and compiler work together, achieving efficient incremental compilation and real-time preview. The article details the design ideas of layout caching, module evaluation memoization, function purity, and the introspection system.

<p><a href="https://lobste.rs/s/hj0exw/typst_designing_for_incrementality">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 06/29/26, 04:31 PM

TL;DR: Typst achieves efficient incremental compilation and real-time preview through constraint memoization (comemo) and a pure function design, making the language and compiler work together. ## Introduction: Typst's Design Goals Typst is a markup-based typesetting system with its own markup language, styling system (`set` and `show` rules), a full scripting layer, and an introspection system. It is designed to be easy to learn and pleasant to use, with the core goal of achieving **real-time preview**—entirely feasible given 2026's hardware. The key is to **co-design the language and its implementation** to support high-performance incremental compilation. ## The Core of Incremental Compilation: Memoization To reuse already compiled results when editing a document, Typst uses **memoization** to remember intermediate compilation results. ### Simple Memoization of Layout A layout function takes inputs like a paragraph and a width and returns a fixed-sized frame. It is a pure function with no side effects. So simply hash the inputs (using `xxhash`) and store the result in a hash map. This is the most basic caching strategy, and it is remarkably effective in reducing layout overhead. ### Module Evaluation and Constraint Memoization The scripting system includes modules, organized using `include` and `import`. If we memoize the `eval` function directly, its inputs include a source file and the filesystem. But the filesystem changes when external files change, causing all `eval` calls to be invalidated. Typst uses the **comemo** (constraint memoization) crate: the filesystem is wrapped in a `Tracked` type. Each time `eval` calls `fs.load`, it records the actual file path that was read and its hash, forming a set of “constraints”. After evaluation finishes, the constraints and output are stored together in the cache. On the next call, we hash the non-tracked arguments to find the entry, then check each constraint individually. The cache is invalidated only when an actually-read file changes, avoiding a full recompilation. ## Functions and Purity User functions in Typst must also be cacheable. The idea is to enforce **pure functions**—no mutable references, no global state. Does this turn the script language into Haskell? Not really. Typst is more like “deterministic Rust without references”, allowing local mutability (e.g., `for` loops), but mutability is encapsulated inside functions. Efficient data passing is achieved through value semantics and reference counting (`Arc`), without needing lifetimes. For example, when returning a vector, cloning into the cache only requires `arc_bump` (incrementing the reference count), offering great performance. Local mutability is implemented via `Arc::make_mut`: check if the reference is unique; if so, mutate in place; otherwise, clone then mutate. This design ensures cache correctness while keeping the script language easy to use. ## Challenges of a Typesetting System: Counters and Table of Contents Pure functions cannot directly use mutable counters (like section numbers) or query the internal state of the document (like a table of contents). Counters seem simple, but a table of contents and cross-references are actually two sides of the same coin: both require document introspection. ### LaTeX's Multiple Iterations LaTeX solves this by writing information to auxiliary files (e.g., `.toc`) and running the compiler multiple times. Users need to run repeatedly, using `latexmk` to automatically iterate until stable. This is a “keep retrying until convergence” approach. ### Typst's Introspection System Instead of relying on mutability, Typst provides **introspection** capabilities: the document can observe its own structure. For example, one can ask “where is the first heading in the document?” and obtain its page coordinates. In this way, symbolic numbering (like chapter numbers) and the table of contents can be implemented via introspection rather than mutable counters. This still respects the pure function constraint while solving traditional typesetting pain points in a more declarative manner. ## Summary Typst achieves efficient incremental compilation by tightly coupling the compiler's memoization features with a pure function language design. Layout caching, constraint-memoized module evaluation, enforced function purity, and the introspection system together form the foundation for Typst's real-time preview. This co-design approach allows the language syntax and implementation to reinforce each other, rather than becoming a burden. Source: https://youtu.be/yWWVhbyOWWE

Similar Articles

@seclink: Classic pitfall of sccache and incremental being mutually exclusive: enabling both results in 20GB of incremental cache yet dependencies being recompiled every time. After turning off incremental: large third-party libraries (tokio/serde/axum/reqwest, etc.) compile once, across…

X AI KOLs Following

Explains the mutual exclusivity issue between sccache and incremental compilation: enabling both leads to 20GB incremental cache consumption and dependencies being recompiled each time. After disabling incremental, large third-party libraries compile once and are reused across projects, achieving a cache hit rate of 53–93% after the first compilation.

Test-Time Memory Construction

arXiv cs.CL

提出 T2Mem 框架,将记忆构建延迟到推理阶段,随推理过程渐进式构建面向查询的记忆,在 LoCoMo 和 LongMemEval 上超越强基线并显著降低记忆构建开销。

Valen's Memory Safety: A New Kind of Borrow Checking

Hacker News Top

Valen 的新文章介绍了一种更灵活的借用检查器(group borrowing),编译器会记住引用指向的位置,以实现比 Rust 更简单灵活的内存安全方案,并已被 Google Carbon 等语言采纳。

@billtheinvestor: Give Claude Code and Codex infinite memory, programming efficiency improved by 92%! The Agentmemory tool has quickly gained 4000+ stars on GitHub and is completely free. It saves all information from your coding sessions through smart compression, and automatically extracts relevant context in future sessions, avoiding re...

X AI KOLs Timeline

Agentmemory is an open-source tool that provides infinite memory for Claude Code and Codex, reducing token usage through intelligent compression, improving programming efficiency, and has gained 4000+ stars on GitHub.

Understanding and Mitigating Inference-Time Overreliance Using Agentic Memory

arXiv cs.AI

该论文研究了LLM智能体中的'记忆过度依赖'现象——即使记忆是良性的、正确存储且被恰当检索,部分证据迁移仍会误导推理。作者提出MemTrim框架,在写入时索引记忆证据、在读取时控制复用,无需重训即可减少过度依赖。