<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez" -->

---
title: Pretext: a 15kb TypeScript library that does browser...
description: Pretext is a new TypeScript library by Cheng Lou (former React core team) that measures browser text dimensions without triggering DOM reflow. It uses the...
canonical: https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Pretext: a 15kb TypeScript library that does browser text layout without touching the DOM | daily.dev
og:description: Pretext is a new TypeScript library by Cheng Lou (former React core team) that measures browser text dimensions without triggering DOM reflow. It uses the...
og:url: https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez
og:image: https://api.daily.dev/og/posts/MEe3G5Jez.png
og:image:alt: Pretext: a 15kb TypeScript library that does browser text layout without touching the DOM
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Pretext: a 15kb TypeScript library that does browser text layout without touching the DOM

**[Collections](https://daily.dev/sources/collections)** · 3 min read · 29 upvotes · 2 comments

## Summary

Pretext is a new TypeScript library by Cheng Lou (former React core team) that measures browser text dimensions without triggering DOM reflow. It uses the Canvas API to measure text width and a custom algorithm for line breaks, separating a one-time preparation pass from a cheap arithmetic layout pass. The result is roughly 500x faster text measurement — 1,000 items drop from ~94ms to ~0.05ms. It supports all languages including bidirectional text, CJK, Arabic, and emojis, weighs 15KB, and outputs to Canvas, SVG, or WebGL. This unlocks practical use cases like virtualized lists, masonry layouts, scroll anchoring, and real-time chat streaming without layout jank.

## Content

Cheng Lou - one of the original React core team members, previously at Facebook Messenger and Midjourney - just released a library that solves a performance problem that's been sitting in browsers since the 1990s.

It's called [Pretext](https://github.com/chenglou/pretext), and it's worth understanding why it matters.

## The actual problem

Every website you've used relies on a text layout system that hasn't fundamentally changed in 30 years. When a browser renders text, it loads a font, measures the text, figures out where lines break, and positions everything vertically. Each step depends on the previous one, and each step forces the browser to pause and recalculate - a process called layout reflow.

You've almost certainly felt this, even if you didn't know what was causing it:

- Slack's scroll position jumping when message heights are calculated wrong
- Google Docs slowing down on long documents because every keystroke recalculates layout for everything below your cursor
- AI chat apps getting janky during streaming because each new token can trigger a line wrap that shifts the entire page

Same root cause every time. Text measurement has always been locked inside the browser's DOM, and there's been no way around it.

Developers have gradually moved other things out of the DOM over the years - rendering to Canvas, custom scroll implementations, JS-based positioning - but text was always the one piece that couldn't move. It was stuck.

## What Pretext does

Pretext bypasses DOM reflow entirely. It uses the browser's Canvas API to measure text width without touching the DOM at all, then uses a custom algorithm to calculate line breaks and text height. The API separates a one-time preparation pass (text segmentation, bidirectional text handling, canvas measurement) from a cheap arithmetic-based layout pass that runs after.

The practical result: measuring 1,000 items drops from around 94ms with dropped frames to about 0.05ms. That's roughly 500x faster in typical cases.

The library:
- Returns exact line breaks, widths, and heights from pure math
- Supports all languages including mixed bidirectional text, CJK, Arabic, and emojis
- Weighs 15 kilobytes
- Was validated by running Claude Code and Codex against browser ground truth for weeks

The API also exposes iterator-style interfaces for variable-width line routing - so you can flow text around floated images, for example - and supports rendering output to Canvas, SVG, or WebGL.

## What this unlocks

The demos are genuinely surprising. Hundreds of thousands of virtualized text boxes running at 120fps with no DOM measurement. Chat bubbles that shrinkwrap to their content with zero wasted pixels - something CSS can't actually do cleanly. Responsive multi-column magazine layouts that reflow dynamically. Variable font ASCII art.

For practical day-to-day use, this is most immediately useful for virtualized lists, masonry layouts, scroll anchoring, and anything that needs to know text dimensions before rendering. The performance gap is large enough that it changes what's feasible to build.

It's open source: `npm install @chenglou/pretext`

## Community discussion

Top comments from developers on daily.dev.

**@testtoast909532** · 1 upvotes

> does it render in canvas?

**@allinonetools** · 1 upvotes

> This is really interesting. Moving text layout out of the DOM could solve a lot of real performance issues, especially for chat apps and editors where reflow becomes a bottleneck.

## Similar posts on daily.dev

- [Pretext.js Bypasses DOM Layout Reflow, Enabling Advanced UX Patterns at 120 FPS](https://daily.dev/posts/pretext-js-bypasses-dom-layout-reflow-enabling-advanced-ux-patterns-at-120-fps-b1lmzt2mp) · InfoQ · 13 upvotes · 0 comments

---

Tags: [#typescript](https://daily.dev/tags/typescript)

[View this post on daily.dev](https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Pretext: a 15kb TypeScript library that does browser text layout without touching the DOM","url":"https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez"},"datePublished":"2026-03-31T08:26:18.950Z","dateModified":"2026-04-03T21:19:03.004Z","description":"Pretext is a new TypeScript library by Cheng Lou (former React core team) that measures browser text dimensions without triggering DOM reflow. It uses the...","isAccessibleForFree":true,"articleSection":"Collections","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Collections","logo":"https://media.daily.dev/image/upload/s--fk_6ycEi--/f_auto,q_auto/v1780996001/logos/collections?_a=BAMAMiWQ0","url":"https://daily.dev/sources/collections"},"commentCount":2,"discussionUrl":"https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":29},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":2}],"keywords":"typescript","timeRequired":"PT3M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Collections","item":"https://daily.dev/sources/collections"},{"@type":"ListItem","position":3,"name":"Pretext: a 15kb TypeScript library that does browser text layout without touching the DOM"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/pretext-a-15kb-typescript-library-that-does-browser-text-layout-without-touching-the-dom-mee3g5jez","comment":[{"@type":"Comment","text":"does it render in canvas?","datePublished":"2026-04-04T19:05:33.993Z","url":"https://daily.dev/posts/MEe3G5Jez#c-MV1uMEuJC","author":{"@type":"Person","name":"Test","url":"https://daily.dev/testtoast909532","image":"https://media.daily.dev/image/upload/s--Lju-sS4X--/f_auto/v1724001914/avatars/avatar_geWfqL9aaZHCYdaFNbrid"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}},{"@type":"Comment","text":"This is really interesting. Moving text layout out of the DOM could solve a lot of real performance issues, especially for chat apps and editors where reflow becomes a bottleneck.","datePublished":"2026-04-02T02:49:46.992Z","url":"https://daily.dev/posts/MEe3G5Jez#c-t0WJEfLOq","author":{"@type":"Person","name":"AllInOneTools","url":"https://daily.dev/allinonetools","image":"https://media.daily.dev/image/upload/s--4ZT8QlF0--/f_auto/v1769790028/avatars/avatar_igzBsWloJeaegzm9bQltZ?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}}]}
```

