text-layout: The Ghost in the Browser: Inside chenglou/pretext

How a pure TypeScript library bypasses the DOM to measure and wrap text 500 times faster.

7 min read · chenglou/text-layout

A massive mechanical printing press jammed by a heavy stone tablet labeled DOM Reflow, illustrating the blocking nature of native DOM text measurement.
Native DOM text measurement acts like a stone jammed in the gears of a high-performance rendering engine.

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).

Cheng Lou, Creator · Repository: chenglou/pretext
Key Takeaways

The DOM's Original Sin

The web's most foundational primitive is actually a massive performance trap. For decades, finding out the exact height of a wrapped paragraph required inserting it into the Document Object Model and asking the browser for its dimensions. This triggers a synchronous DOM reflow. The browser has to stop whatever it is doing, recalculate the layout of the entire page, and hand back a number.

This synchronous blocking is why complex user interfaces drop frames. When building infinite scrolls, custom canvas editors, or WebGL experiences, relying on native DOM measurement is a guaranteed bottleneck. Every call to getBoundingClientRect is a penalty.

Compiling Text Like Code

Pretext solves this by treating text layout like a compiled language. It separates the expensive font measurement from the container-aware wrapping calculations. This two-phase pipeline is the core differentiator of the library.

The two-phase pipeline: prepare() measures the glyphs once, and layout() calculates the wrapping purely through math.

The first phase is prepare. It normalizes whitespace, segments the text, and measures the individual pieces using the Canvas API. This happens exactly once. The second phase is layout. Because the widths are already cached, adjusting the container size becomes an exercise in pure arithmetic.

import { prepare, layout } from '@chenglou/pretext'

// Phase 1: Measure once (Cost: ~19ms for 500 paragraphs)
const prepared = prepare('Your complex multi-language text here', '16px Inter')

// Phase 2: Wrap infinitely (Cost: ~0.09ms for 500 paragraphs)
const { height, lineCount } = layout(prepared, maxWidth, 20)
MetricDOM ReflowPretext
Initialization CostLow~19ms (500 blocks)
Recalculation on ResizeExtremely High (Reflow)~0.09ms (Math only)
EnvironmentBrowser DOM OnlyUniversal (Canvas, WebGL, SVG)

Reverse-Engineering the Browser

Achieving this speed is useless without pixel-perfect accuracy. Browsers have spent 30 years refining text rendering. Matching that natively in TypeScript required an unconventional approach.

A stippled editorial portrait of Cheng Lou.

To ensure Pretext's mathematical output matched actual browser rendering, Lou deployed AI agents to run automated layout tests across varying widths for weeks. They brute-forced the edge cases, comparing the mathematical model against the native C++ engine until the two aligned perfectly.

The Unicode Labyrinth

Text layout is rarely just about splitting spaces. To be globally useful, a layout engine must handle the Unicode Bidirectional Algorithm (UAX #9) and Line Breaking (UAX #14). A naive implementation fails immediately when encountering Arabic scripts, emojis, or soft hyphens.

A magnifying glass held over a single line of mixed-language text. Beneath the characters, tiny mechanical arrows and switches dictate the reading direction, resembling traces on a circuit board.
The Unicode Bidirectional algorithm requires tracking complex directional state across mixed-language strings.

Pretext implements these algorithms in pure JavaScript. It classifies every character and tracks directional state overrides. This allows the library to handle mixed-direction text flawlessly without asking the browser to intervene.

Escape Velocity

Decoupling text layout from the DOM unlocks entirely new capabilities for web developers. It provides the low-level primitives necessary to build complex, deterministic typography.

A split composition: on the left, a giant monolithic stone block being dragged up a hill by ropes. On the right, a nimble skeleton-like abacus floating effortlessly in the air.
Traditional DOM reflow relies on heavy, monolithic recalculations, while Pretext relies on lightweight, cached arithmetic.

With Pretext, rendering multi-column text, wrapping words around arbitrary animated shapes, or building custom WebGL interfaces at 120 frames per second is no longer a theoretical exercise. It is just math.