Um dos criadores do React acabou de tornar o CSS Obsoleto - ou uma parte dele - E ele usou IA pra fazer isso.
Cheng Lou, o cara por trás do React, ReasonML, e que trabalhou no Messenger e no Midjourney, lançou o Pretext.
Uma biblioteca TypeScript de poucos KBs que mede e faz layout de texto sem tocar no DOM. Sem CSS. Sem reflow. Aritmética pura.
O que isso resolve:
→ Layout reflow é a maior fonte de travamento na web moderna
→ CSS foi desenhado há 30 anos pra documentos estáticos
→ Toda vez que um app precisa saber a altura de um texto, o browser congela a thread principal por dezenas de milissegundos
→ Chat bubbles, dashboards responsivos, layouts de revista… tudo refém de uma pipeline de 1996
Pretext elimina isso. Zero reflows. ~500x mais rápido. Poucos KBs.
O detalhe que ninguém está comentando:
Cheng Lou construiu isso usando Claude Code e Codex. Alimentou a IA com o ground truth do browser e mandou ela iterar até convergir na precisão.
Suporta CJK, árabe RTL, emojis, clusters de grafemas. Tudo.
Isso não é uma lib qualquer. É infraestrutura de UI sendo escrita por IA sob supervisão de um dos melhores engenheiros de front-end vivos.
A era em que humanos escrevem cada linha de código de infraestrutura está acabando.
Os melhores engenheiros do mundo já estão usando IA como co-piloto para resolver problemas que ninguém resolveu em 30 anos.
Pretext
Biblioteca JavaScript/TypeScript pura para medição e layout de texto multilinha. Rápida, precisa e com suporte a praticamente todos os idiomas (inclusive alguns que você nem imaginava). Permite renderização em DOM, Canvas, SVG e futuramente server-side.
O Pretext evita a necessidade de medições no DOM (como getBoundingClientRect ou offsetHeight), que causam layout reflow — uma das operações mais caras no navegador. Ele implementa sua própria lógica de medição de texto, usando o motor de fontes do próprio navegador como base.
Instalação
npm install @chenglou/pretext
Demos
Clone o repositório, execute:
bun install
bun start
Depois abra /demos no navegador (sem barra no final, devido a um bug do Bun).
Ou veja online:
API
O Pretext atende dois principais casos de uso:
1. Medir a altura de um parágrafo sem usar o DOM
import { prepare, layout } from '@chenglou/pretext'
const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')
const { height, lineCount } = layout(prepared, textWidth, 20)
-
prepare()faz o trabalho pesado inicial:- normaliza espaços
- segmenta o texto
- aplica regras de quebra
- mede segmentos usando canvas
-
layout()é leve:- apenas cálculos matemáticos
- sem reflow ou acesso ao DOM
Para comportamento tipo textarea (com espaços, tabs e quebras preservadas):
const prepared = prepare(textareaValue, '16px Inter', { whiteSpace: 'pre-wrap' })
const { height } = layout(prepared, textareaWidth, 20)
Performance (benchmark atual)
prepare()→ ~19ms (para 500 textos)layout()→ ~0.09ms
Suporta:
- emojis
- textos bidirecionais
- múltiplos idiomas
Benefícios principais:
- virtualização precisa (sem estimativas)
- layouts customizados (masonry, etc.)
- validação de UI em desenvolvimento
- evitar layout shift ao carregar conteúdo
2. Layout manual das linhas
Use prepareWithSegments:
import { prepareWithSegments, layoutWithLines } from '@chenglou/pretext'
const prepared = prepareWithSegments('AGI 春天到了. بدأت الرحلة 🚀', '18px "Helvetica Neue"')
const { lines } = layoutWithLines(prepared, 320, 26)
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[i].text, 0, i * 26)
}
Outras APIs úteis
walkLineRanges
let maxW = 0
walkLineRanges(prepared, 320, line => {
if (line.width > maxW) maxW = line.width
})
Retorna a largura da maior linha — útil para calcular largura ideal de container.
layoutNextLine
Permite layout dinâmico linha a linha:
let cursor = { segmentIndex: 0, graphemeIndex: 0 }
let y = 0
while (true) {
const width = y < image.bottom ? columnWidth - image.width : columnWidth
const line = layoutNextLine(prepared, cursor, width)
if (line === null) break
ctx.fillText(line.text, 0, y)
cursor = line.end
y += 26
}
Permite:
- fluxo de texto ao redor de imagens
- layouts não lineares
Glossário da API
Caso 1
prepare(text, font, options?)
layout(prepared, maxWidth, lineHeight)
Caso 2
prepareWithSegments(text, font, options?)
layoutWithLines(prepared, maxWidth, lineHeight)
walkLineRanges(prepared, maxWidth, callback)
layoutNextLine(prepared, cursor, maxWidth)
Tipos
type LayoutLine = {
text: string
width: number
start: LayoutCursor
end: LayoutCursor
}
type LayoutCursor = {
segmentIndex: number
graphemeIndex: number
}
Helpers
clearCache()
setLocale(locale?)
Limitações
O Pretext não é um motor completo de renderização de fontes.
Suporta principalmente:
-
white-space: normal -
word-break: normal -
overflow-wrap: break-word -
line-break: auto -
pre-wrappreserva espaços, tabs e quebras -
fontes
system-uipodem gerar inconsistência (especialmente no macOS) -
palavras podem quebrar em larguras muito pequenas