finds.dev← search

// the find

chenglou/pretext

★ 50,691 · TypeScript · MIT · updated Oct 2026

Fast, accurate & comprehensive text measurement & layout

Pretext is a TypeScript library that works out how multiline text will wrap and how tall it will be without asking the DOM, so it never calls getBoundingClientRect or offsetHeight and never forces a reflow. It measures segments once with canvas in prepare(), then line-breaking is arithmetic in layout(). It suits anyone who needs text dimensions before rendering, such as virtualized lists, masonry, shrink-wrapped bubbles, or checks that a button label fits.

The prepare/layout split is the right cut. The canvas measurement and segmentation happen once, and a resize only reruns layout() over cached widths, which is the only way this pays off in a resize-heavy UI. The low-level surface goes past a height calculator: walkLineRanges and measureLineStats support searching for a width that gives balanced or shrink-wrapped text, and layoutNextLineRange changes width per line for text flowing around a float. The harness/recordings directory holds browser-recorded results for Chrome, Firefox and Safari, and the engine-data folders are pinned to specific engine versions, so the accuracy claim has something behind it. The caveats section is unusually candid about platform traps: system-ui is unsafe on macOS, Firefox rounds font sizes, a lone carriage return is a break here but not in browsers, and small emoji measure too wide in workers. Most libraries in this space would bury that.

Accuracy depends on matching each engine's line-break and shaping behavior, and that matching is maintained by hand. Each browser release means regenerating engine-data, and between regenerations the library can drift without any signal. The supported CSS is narrow. Only white-space normal and pre-wrap, word-break normal and keep-all, and overflow-wrap break-word are handled. letter-spacing takes a pixel number only, and font-variation-settings, font-feature-settings and word-spacing are ignored. Real page CSS can therefore disagree with layout(), and the API gives no warning at the call site. The runtime requirements are hard: Canvas 2D text measurement, Unicode property escapes, and Intl.Segmenter for Thai, Lao, Khmer and Myanmar. It throws instead of degrading, which is fine for a modern browser target and a problem for older clients or server-side rendering. Font loading is a footgun. prepare() measures whichever font is active at the time, so calling it before a web font loads caches fallback widths until someone calls clearCache() and prepares the text again. The README documents this, but the API does not enforce it.

View on GitHub → Homepage ↗

// want more like this?

We dig through GitHub every week and send a few repos picked for what you actually care about — each with an honest take like this one.

Get finds in your inbox → Search again →