Pure JavaScript/TypeScript library for multiline text measurement & layout. Fast, accurate & supports all the languages you didn't even know about. Allows rendering to DOM, Canvas, SVG and soon, server-side. Pretext side-steps the need for DOM measurements (e.g. getBoundingClientRect, offsetHeight), which trigger layout reflow, one of the most expensive operations in the browser. It implements its own text measurement logic, using the browsers' own font engine as ground truth (very AI-friendly iteration method). npm install @chenglou/pretext Clone the repo, run bun install, then bun start, and open the /demos in your browser (no trailing slash. Bun devserver bugs on those) Alternatively, see them live at chenglou.me/pretext. Some more at somnai-dreams.github.io/pretext-demos Pretext serves 2 use cases: 1. Measure a paragraph's height without ever touching DOM import { prepare, layout } from '@chenglou/pretext' const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter') const { height, lineCount } = layout(prepared, textWidth, 20) // pure arithmetics. No DOM layout & reflow! prepare() does the one-time work: normalize whitespace, segment the text, apply glue rules, measure the segments with canvas, and return an opaque handle. layout() is the cheap hot path after that: pure arithmetic over cached widths. If you want textarea-like text where ordinary spaces, \t tabs, and \n hard breaks stay visible, pass { whiteSpace: 'pre-wrap' } to prepare() / prepareWithSegments(). const prepared = prepare(textareaValue, '16px Inter', { whiteSpace: 'pre-wrap' }) const { height } = layout(prepared, textareaWidth, 20) On the current checked-in benchmark snapshot: prepare() is about 19ms for the shared 500-text batch layout() is about 0.09ms for that same batch We support all the languages you can imagine, including emojis and mixed-bidi, and caters to specific browser quirks The returned height is the crucial last piece for unlocking web UI's: proper virtualization/occlusion wi...
First seen: 2026-03-29 17:56
Last seen: 2026-03-29 19:57