Browsers expose text sizing only through DOM queries that trigger synchronous reflow — a huge cost when text changes frequently (resizes, streaming tokens, virtual lists). Pretext separates measurement from layout: measure each text segment once using Canvas and Intl.Segmenter, cache the widths, then run line-breaking as pure arithmetic. The result is predictable, fast layout that keeps UI frame rates steady when text is the bottleneck.
What Sets It Apart
-
Two‑phase architecture with cached measurements: a relatively heavier one‑time prepare pass (segmenting text, applying glue rules, measuring segments on a Canvas) and a near‑free hot path layout that uses only arithmetic over cached widths. This makes repeated layouts (resizes, streaming updates, virtualization) extremely cheap compared with DOM reflow.
-
Wide language and layout coverage: handles Latin, CJK, Arabic, Hebrew, Thai, Khmer, Indic scripts, emoji and mixed bidirectional text. It implements browser‑like whitespace and word‑break behaviors and offers both opaque fast handles (prepare/layout) and rich segment handles for manual per-line composition.
-
Designed for real UI constraints: enables accurate virtualization without speculative hidden DOM measurement, deterministic heights for streamed AI responses (no layout shift), and manual line iteration for canvas/SVG/WebGL rendering or complex flow around floats.
-
Small, dependency‑free runtime that works in browsers, Node/Deno/Bun and workers; however measurement relies on Canvas 2D and Intl.Segmenter so runtime support matters.
Who it's for and tradeoffs
Great fit if you build chat UIs, virtualized feeds, streaming text renderers, custom magazine‑style layouts, or any interface that needs reliable text heights without blocking the main thread. It saves repeated reflows when the same text is laid out many times (different widths, streaming growth) and enables deterministic per-line control for bespoke renderers.
Look elsewhere if you need a full page layout engine (Pretext handles text only), if your runtime lacks Intl.Segmenter or Canvas measurement, or if you cannot guarantee the font is loaded before prepare() (font metrics must be available to yield accurate widths). Also note the prepare pass is nontrivial (measuring work is a one‑time cost per text+font), so tiny one‑off texts that are laid out once may not benefit.
Where it fits
Pretext is not a replacement for DOM rendering — text still lives in the DOM when you render to it — but it replaces expensive size queries. Compared with the default approach of temporary hidden DOM measurement, Pretext shifts cost into a deterministic prepare step and makes subsequent layout calculations cheap, predictable, and friendly to high‑frequency UI updates such as token streaming from LLMs.
Implementation notes
Internally it uses Intl.Segmenter for locale‑aware segmentation, Canvas.measureText for segment widths, and a line‑breaking algorithm that operates on numeric widths. The library exposes both high‑level fast APIs for height measurement and low‑level line/segment APIs for manual composition and streaming. Practical caveats: font must be loaded before measuring, some advanced CSS text features and fine glyph positioning are outside its scope, and server‑side use requires an environment that can provide measurement backends (there is experimental HarfBuzz support for headless setups).