Text layout on the web has always been a quiet tax. Every time your browser needs to know how tall a paragraph is, it stops everything, recalculates the entire document geometry, and hands you the answer. Do it a thousand times a second, in an animation, a drag handler, a live editor, etc, and you've just handed the browser a performance death sentence. Cheng Lou decided to fix that.
01. THE PROBLEM
The browser's layout engine is both your best friend and your worst enemy. Functions like getBoundingClientRect(), offsetHeight, and scrollHeight return accurate answers, but at a steep cost: they force a synchronous layout recalculation of the entire page, a process called layout thrashing.
// This looks innocent. It's not.
for (const el of elements) {
const height = el.offsetHeight; // forces reflow
el.style.top = height + "px"; // invalidates layout again
}Each read-write cycle triggers a full reflow. In a tight loop or animation frame, this cascades into dropped frames, jank, and UI that visibly struggles to keep up. The standard workarounds like debouncing, batching reads before writes, ResizeObserver, reduce the damage but don't eliminate it.
For anyone building fluid editorial layouts, real-time text editors, multi-column magazine grids, or interactive typography, the DOM is simply the wrong tool. The measurements come too late and cost too much.
02. THE APPROACH
Pretext sidesteps the DOM entirely. Instead of asking the browser "how tall is this text?" after rendering it, Pretext computes the answer through pure arithmetic, the same way a typesetting engine would.
The key insight: browsers already expose fast, non-reflow-inducing font metrics through the Canvas 2D API (context.measureText()). Pretext uses these measurements as ground truth, then implements the full CSS text layout algorithm, word wrapping, line breaking, overflow-wrap, word-break, bidirectional text, in pure JavaScript.
import { prepare, layout } from "pretext";
// One-time analysis per text + font combo (~19ms for 500 texts)
const handle = prepare("The quick brown fox...", {
font: "16px Inter",
lineHeight: 1.5,
});
// Zero-reflow height calculation at any width (0.09ms)
const { height } = layout(handle, { width: 640 });The prepare() call does the expensive work once: it measures all the individual glyphs and builds internal lookup tables. After that, layout() is pure math, no DOM access, no reflow, no waiting.
03. THE NUMBERS
The performance gap is not marginal.
| Method | 500 texts | Per layout |
|---|---|---|
offsetHeight (DOM) | ~27,000ms | ~54ms |
getBoundingClientRect | ~8,500ms | ~17ms |
| Pretext | ~19ms prepare + ~45ms layout | ~0.09ms |
At 0.09ms per layout call, you can reflow 10,000 text elements inside a single 16ms animation frame and still have 9ms left over. The library itself is 15KB, smaller than most icon fonts.
TIP
The layoutNextLine() API accepts a different available width per line, enabling text to flow around arbitrary shapes, like what happens in the demo below.
04. WHO BUILT IT
Cheng Lou is not a newcomer. He was a core contributor to the React team at Facebook, the creator of ReasonML (a typed functional language targeting JavaScript), and later a founding engineer at Midjourney where he worked on real-time UI at scale.
When he posted Pretext on GitHub in March 2026, the reaction was immediate. Vercel CEO Guillermo Rauch called it "so good." The repo hit trending within hours. Engineers who had spent years fighting DOM reflow in production applications recognized the problem instantly and recognized that this was a real solution, not a workaround.
Lou described the motivation bluntly: text layout had become "hellish infrastructure" that nobody wanted to own. Pretext is his attempt to make it infrastructure you don't have to think about.
05. LIVE DEMO
The demo below shows what Pretext's layoutNextLine() API makes possible: text reflowing around a moving shape in real time, at 60fps, with no DOM involvement. Move your cursor over the canvas and the circle follows it, and the paragraph reroutes itself around the obstacle on every frame.
PRETEXT_LIVE_REFLOW // DRAG_TO_INTERACT
This kind of interaction was previously impractical in a browser. The moment the circle moves, every line must be re-measured and re-laid-out. With DOM-based measurement, that's hundreds of reflows per second. With Pretext's approach, it's arithmetic that completes in under a millisecond.
06. WHAT THIS UNLOCKS
The performance headroom Pretext creates isn't just about speed, more importantly it's about what becomes possible for the first time.
- —Fluid multi-column editorial layouts that reflow live as the user resizes the window, with no observable lag
- —Text-around-shape wrapping at interactive framerates (as shown above)
- —Server-side text layout, run the same code in Node.js to pre-calculate column heights before the page renders, eliminating layout shift
- —ASCII particle systems where thousands of characters are individually positioned using calculated typographic metrics
- —Variable-width text streams for typographic animations that would otherwise require a canvas renderer and a custom font parser
The library also handles everything the web throws at text: RTL and bidirectional scripts, platform-specific emoji width quirks, white-space: pre-wrap semantics, and the full CSS word-breaking algorithm.
NOTE
Pretext is open source and available at github.com/chenglou/pretext. The official demo site at chenglou.me/pretext showcases eight production-grade examples including masonry layouts, dynamic editorial spreads, and full-screen ASCII particle systems.
Text layout has been a solved problem in desktop software for thirty years. On the web, it's been a recurring nightmare. Pretext is the first library that treats it as the infrastructure problem it actually is and solves it properly.