Pretext.js is a pure JavaScript/TypeScript text layout engine that measures and positions multiline text entirely through arithmetic — never touching the DOM — achieving 600× faster performance than traditional getBoundingClientRect calls.
What is Pretext.js?
Pretext.js is a pure JavaScript/TypeScript text measurement and layout engine created by Cheng Lou (chenglou), a former React core team member now at Midjourney. It takes a string of text and a font specification, measures every word once via Canvas and Intl.Segmenter, then computes line breaks and heights using pure arithmetic — outputting exact pixel heights and line counts without any DOM access. The library runs in any modern browser and is framework-agnostic, weighing approximately 15KB with zero runtime dependencies. It is MIT-licensed and available on npm as @chenglou/pretext.
Key Features
- Zero DOM reads — The
layout()function performs no getBoundingClientRect calls, no reflow, and no layout thrashing. After preparation, all computation is arithmetic. - Real font metrics — Glyph widths are measured using the browser's own Canvas
measureText()API, matching what the browser would actually render. - Multilingual support — Fully supports CJK, Arabic, Hebrew, Thai, Hindi, Korean, and bidirectional text via Unicode segmentation and
Intl.Segmenter. - TypeScript-native — Written in TypeScript with precise types for every function; no additional
@typespackages needed. - Reusable prepared handles — One
prepare()call works for any container width; compute heights for mobile, tablet, desktop from the same handle. - Zero runtime dependencies — No external packages or polyfills; relies only on standard browser APIs.
- 600× faster than DOM — Lays out 1,000 blocks in approximately 2 milliseconds, compared to ~94 ms with forced synchronous reflow.
Who is it for?
- Performance-sensitive web developers building virtual scrolling lists, code editors, or chat interfaces where measuring thousands of text items per frame would otherwise cause dropped frames.
- UI framework authors integrating text measurement into reactive libraries (React, Vue, Svelte) to avoid layout shift during streaming or resizing.
- Internationalization engineers working with multilingual content mixing scripts like CJK, Arabic, and Latin in a single view, requiring accurate per-script line breaking.
- Creative developers building text animations, fluid simulations, or interactive typography where real-time reflow around obstacles is needed — like the editorial engine demo with draggable orbs.
What can you do with Pretext.js?
- Build variable-height virtual scrollers: Render 10,000 items with text heights calculated without DOM reads, maintaining 60fps scrolling on any device. View example →
- Eliminate layout shift in AI chat bubbles: Pre-compute bubble heights for streaming AI responses before they finish rendering, preventing jumpiness. View example →
- Handle multilingual content feeds: Display a social feed mixing Chinese, Arabic, Korean, and Latin text in a single virtualized list with accurate measurements for each script. View example →
- Create interactive text animations: Use the editorial engine demo to flow text around draggable obstacles in real time, something CSS Shapes cannot do. Open Playground →
- Play the Pretext Breaker game: A Breakout-style arcade game where every pixel is rendered with text, powered by Pretext.js. Play the Game →
How does Pretext.js work?
- Segment the text: Normalize whitespace, apply Unicode line-break rules, and split the string into measurable units using the browser's text segmentation via
Intl.Segmenter. - Measure with Canvas: Feed each segment through Canvas
measureText()to get real glyph advance widths from the font engine. Results are cached in a prepared handle. - Layout with pure arithmetic: Given a container width, compute line breaks by summing segment widths. Multiply line count by line-height to return height. No DOM access occurs during layout.
FAQ
Is Pretext.js free?
Yes, Pretext.js is MIT-licensed and free for any use — personal, commercial, or open source.
Does Pretext.js support my language?
Pretext.js supports 12+ writing systems including CJK, Arabic, Hebrew, Thai, Hindi, Korean, and Latin-based scripts. It uses Unicode segmentation and Intl.Segmenter for correct bidirectional text handling.
How does Pretext.js compare to traditional DOM measurement?
Pretext.js is approximately 600× faster. A 1,000-item layout using DOM getBoundingClientRect takes roughly 94 ms (6 dropped frames at 60fps), while Pretext.js completes in about 2 ms — all without forced synchronous reflow.
Can I use Pretext.js with React or other frameworks?
Yes, Pretext.js is framework-agnostic. It works with React, Vue, Svelte, or vanilla JavaScript. The library provides only prepare() and layout() functions that return plain values, so integration is straightforward.









