Pretext: mehrzeiligen Text messen und verteilen, ohne das DOM zu berühren
chenglou/pretext · 50.570★ · 2.739 forks
Alles Wissenswerte über chenglou/pretext: eine JavaScript/TypeScript-Bibliothek, die die Höhe, den Zeilenumbruch und die Bereiche eines Absatzes berechnet, indem sie die Typografie-Engine des Browsers als Referenz nutzt — ohne DOM-Knoten auf dem heißen Pfad einzufügen oder zu messen.
Desambiguierung: Dieser Bericht dokumentiert
chenglou/pretext(Textmessungs-Bibliothek, npm-Paket@chenglou/pretext, erstellt im März 2026). Nicht zu verwechseln mitPreTeXtBook/pretext(459 Sterne), einem Autoren- und Veröffentlichungssystem für akademische Dokumente, oder mitpretext-project/pretext-project.github.io, einer Sammlung von Social-Engineering-Vorwänden.
Was Pretext ist
Pretext ist eine JavaScript/TypeScript-Bibliothek zum Messen und Verteilen mehrzeiliger Absätze. Sie löst eine Operation, die klein erscheint, aber viele Oberflächen prägt: zu wissen, wie viele Zeilen ein Text bei einer gegebenen Breite einnehmen und wie hoch er sein wird, ohne ihn im DOM zu rendern und getBoundingClientRect() oder offsetHeight abzufragen — Lesevorgänge, die eine Neuberechnung des Layouts (Reflow) erzwingen, eine der teuersten Operationen im Browser.
Das Projekt trennt zwei Operationen. prepare() erledigt die Arbeit, die vom Text und der Schriftart abhängt — Leerzeichen normalisieren, mit Intl.Segmenter segmentieren, „Klebe”-Regeln anwenden (NBSP, ZWSP, weiche Trennstriche, harte Umbrüche) und die Segmente mit Canvas messen — und liefert ein wiederverwendbares opakes Handle. layout() nimmt dieses Ergebnis, eine maximale Breite und eine Zeilenhöhe entgegen und berechnet height und lineCount durch Arithmetik über zwischengespeicherte Breiten. Bei einer Größenänderung oder in einem Virtualisierungsdurchlauf läuft nur der zweite Teil erneut, nicht die gesamte Analyse.
Pretext versucht nicht, die CSS-Layout-Engine zu ersetzen oder zu einer vollständigen Schriftrendering-Engine zu werden. Es ist ein spezialisiertes Werkzeug für den Fall, dass man einen Textfluss aus JavaScript heraus vorhersagen oder kontrollieren muss: Virtualisierung, Canvas, SVG, WebGL, dynamisches redaktionelles Design, Animation, Etikettenvalidierung während der Entwicklung und (laut README demnächst) serverseitiges Rendering.
Der Ursprung
Das Repository wurde am 7. März 2026 von Cheng Lou (chenglou) erstellt, der laut Simon Willisons Blog zuvor React-Core-Entwickler und der ursprüngliche Schöpfer der Animationsbibliothek react-motion (21.914 Sterne) war. Das Paket @chenglou/pretext wurde erstmals am 27. März 2026 auf npm veröffentlicht (Version 0.0.0); das GitHub-Repository stammt von etwa zwanzig Tagen zuvor, was auf eine private Entwicklung vor dem öffentlichen Launch hindeutet.
Das README erkennt explizit das Projekt text-layout von Sebastian Markbåge als Vorläufer an (ein Fork bleibt erhalten, chenglou/text-layout, mit 34 Sternen) sowie dessen Architektur: measureText von Canvas für das Shaping, bidi-Daten basierend auf pdf.js und Streaming-Zeilenumbrüche. Das README beschreibt zudem eine besondere Entwicklungsmethode: Die Engine wurde „sehr KI-freundlich” iteriert, indem Coding-Agenten wie Claude Code und Codex die Ground Truth des Browsers gezeigt und sie über Wochen hinweg dazu gebracht wurden, bei jeder relevanten Containerbreite dagegen zu messen und zu iterieren.
Die Verifizierung ist ein charakteristisches Merkmal des Ursprungs: Tests renderten eine vollständige Kopie von Der große Gatsby in mehreren Browsern, um zu bestätigen, dass die geschätzten Messungen korrekt waren, und später kam der Ordner corpora/ mit derselben Methode über lange gemeinfreie Dokumente auf Thai, Chinesisch, Koreanisch, Japanisch, Arabisch und anderen hinzu.

Philosophie und Prinzipien
Ihr Kernprinzip ist es, das Teure vom Wiederholbaren zu trennen: einmal analysieren und messen, und Zeilenumbrüche bei vielen Breiten mit zwischengespeicherten Daten neu berechnen. Das README warnt wörtlich: „Führe prepare() nicht erneut für denselben Text und dieselbe Konfiguration aus; das würde seine Vorberechnung zerstören.” Das ist der Leistungsvertrag: prepare() ist teuer, aber einmalig; layout() ist der heiße Pfad — sub-millisekundenschnell, ohne DOM-Lesevorgänge, ohne Canvas-Aufrufe und ohne String-Arbeit.

Ein weiteres Prinzip, sichtbar im Code und in der internen Dokumentation, ist die Nutzung der Font-Engine des Browsers als Referenz, statt ganz CSS neu zu erfinden. Pretext modelliert CSS-Eigenschaften, die außerhalb der canvas.font-Abkürzung liegen (wie font-optical-sizing oder font-feature-settings), nicht separat und beschränkt sein Ziel auf gängige Textkonfigurationen: white-space: normal und pre-wrap, word-break: normal und keep-all, overflow-wrap: break-word, line-break: auto und letter-spacing als numerischer Pixelwert. Diese bewusste Enge erklärt sowohl seine relative Präzision als auch seine Grenzen.
Der Ansatz zur Korrektur plattformspezifischer Eigenheiten — ein Bug-„Kontobuch” (PLATFORM_BUGS.md) mit Links zu Chromium, Mozilla und WebKit, Reproduktionen und per Fähigkeitserkennung ausgelösten Korrekturen — spiegelt eine Philosophie der Ehrlichkeit wider: Statt universelle Genauigkeit zu versprechen, dokumentiert es, wo es von jedem Browser abweicht und wie das gemildert wird.

Wie es funktioniert
Der Browser berechnet die endgültige Größe eines Elements innerhalb eines Baums aus Stilen, Schriftarten, Containern und Flussregeln. Das Abfragen von Geometrie nach DOM-Änderungen kann ihn zwingen, diese Arbeit zu synchronisieren. Für eine Handvoll statischer Etiketten ist das irrelevant; bei großen Listen, in Streaming eintreffenden Nachrichten, Animationen oder vielen Höhenkorrekturen erzeugt das Abwechseln von Schreib- und Lesevorgängen Layout-Thrashing und sichtbare Sprünge.
Pretext umgeht den Layoutbaum für die Schätzung. Es nutzt CanvasRenderingContext2D.measureText(), das Textmetriken gemäß der aktiven Schriftart zurückgibt, als Messreferenz; danach setzt es die Zeilen im Nutzercode zusammen. Der Vorteil ist nicht, dass Canvas magisch schneller als CSS insgesamt ist, sondern dass der heiße Pfad von layout() weder ein temporäres Element einfügen noch Geometrie vom DOM erfragen muss.

Der Kern folgt dieser Sequenz:
- Vorbereitung.
prepare(text, font, options)nimmt den Text und einen Font-Wert im von Canvas akzeptierten Format entgegen (zum Beispiel16px Inter). Es segmentiert den Inhalt, misst die Abschnitte einmal und liefert ein opakes Handle. Optionen:{ whiteSpace: 'pre-wrap' }, um Leerzeichen, Tabulatoren und harte Umbrüche zu erhalten;{ wordBreak: 'keep-all' }fürword-break: keep-all(CJK/Hangul);{ letterSpacing: n }in CSS-Pixeln. - Verteilung.
layout(prepared, maxWidth, lineHeight)löst auf, wie viele Zeilen passen, und liefert{ height, lineCount }. Es ist der Schritt, der wiederholt werden soll, wenn sich die Breite ändert.

- Manuelle Kontrolle, falls nötig.
prepareWithSegments()undlayoutWithLines()liefern die Zeilen;walkLineRanges(),measureLineStats(),layoutNextLineRange()undmaterializeLineRange()erlauben es, sie Zeile für Zeile zu durchlaufen, ohne den gesamten Text zu materialisieren. Damit lässt sich in Canvas, SVG oder um ein Hindernis herum zeichnen, dessen Breite sich pro Zeile ändert (das README enthält ein Beispiel, das Text um ein schwebendes Bild herum fließen lässt).

Das Design stützt sich auf Browser-APIs, nicht auf eigene typografische Tabellen: Canvas liefert die Breite der Segmente, und Intl.Segmenter hilft, Wörter und Grapheme für Sprachen, Emojis und Schriftsysteme ohne Leerzeichen zu unterteilen. Das ist wichtig, weil das Zerschneiden eines Strings nach UTF-16-Indizes nicht dem Zerschneiden sichtbarer Zeichen entspricht.
Offizieller und halboffizieller Status
Die offizielle Oberfläche ist das README (die öffentliche Wahrheitsquelle für Beispiele und Grenzen), die Entwicklungsdokumentation (DEVELOPMENT.md), das Plattform-Bug-Register (PLATFORM_BUGS.md), das CHANGELOG.md, die Demos unter chenglou.me/pretext und das npm-Paket @chenglou/pretext. Es ist Teil keines Marketplace und keines formalen Standards; es gibt keine Organisation, die es im Sinne einer Zertifizierung „unterstützt”.
Seine Halboffizialität besteht in der Praxis in der Übernahme durch TanStack Virtual: Die offizielle TanStack-Website widmet eine Dokumentationsseite („Text Measurement with Pretext”) seiner Nutzung als Höhenschätzer für textdominierte Zeilen in Chats, Streams, Feeds, Kommentaren, Changelogs und Benachrichtigungen, wobei TanStack die Kontrolle über Scroll, sichtbaren Bereich und Position behält. Keines dieser Signale stellt ein Vendor-Endorsement der Methodik oder ihrer Ergebnisse dar; es sind Integrationen und technische Referenzen, keine Standardbezeichnung.

Das Ökosystem
Pretext wurde schnell zu einer Referenzplattform für eine Welle von Ports, Adaptern und Experimenten.
Repositories des Autors: chenglou/pretext (die Hauptbibliothek), chenglou/text-layout (34 Sterne, Markbåges früheres Projekt, als Vorläufer erhalten), chenglou/react-motion (21.914 Sterne, die Animationsbibliothek, deren ursprünglicher Schöpfer Lou war) und chenglou/freerange (594 Sterne, statische @fit-Prüfungen für TypeScript-Layoutcode).
Ports zu anderen Sprachen und Plattformen: tornikegomareli/swift-pretextkit (183 Sterne, ein Swift-Port für Apple-Plattformen, veröffentlicht drei Tage nach dem Original), wieslawsoltes/PretextSharp (27 Sterne, Textvorbereitung und Zeilenlayout für SkiaSharp), craigm26/pretext_dart (8 Sterne) und nathankim0/pretext_flutter (7 Sterne, Dart/Flutter-Ports), waleed-qamar/flutter_pretext (35 Sterne, ein weiterer Flutter-Port), hyj1230/pretext-py (4 Sterne, eine Python-Neuimplementierung), mjshin82/UnityPretext (46 Sterne, ein Unity-Adapter) und fifteen42/pretext-video (90 Sterne, verwandelt die Webcam in lebendige Typografie durch Kombination von Pretext mit MediaPipe).

Adapter für Frameworks und Tooling: JubaKitiashvili/expo-pretext (259 Sterne, sagt React-Native-Texthöhen vor dem Rendern voraus), Agent-Pattern-Labs/textura (154 Sterne, „Pretext x Yoga = Textura”, eine DOM-lose Layout-Engine), BaselAshraf81/layout-sans (67 Sterne, eine reine TypeScript-2D-Flex-/Grid-Layout-Engine, angetrieben von Pretext), LucasBassetti/react-pretext (2 Sterne, ein Headless-React-Adapter), BALOTIAS/vite-pretext (4 Sterne, ein konfigurationsfreies Vite-Plugin zur Beseitigung textbedingter CLS), nikilok/virtual-text-layout (4 Sterne, ein React-Hook, der measureElement von TanStack Virtual ersetzt) und lucascrespo23/pinch-type (112 Sterne, „zoome mit Pinch-Geste den Text, nicht die Seite”).
Kuratierte Listen und benachbarte Projekte: bluedusk/awesome-pretext (35 Sterne, eine kuratierte Liste von Demos und Tutorials), AsharibAli/pretext-skills (12 Sterne) und yaniv-golan/pretext-skill (15 Sterne), „Skills” für KI-Agenten. Als direkter Vergleich veröffentlichte leeoniya uWrap.js (erwähnt in HN 43583478), eine ~2 KB große Bibliothek zur Schätzung der ASCII-Zeilenhöhe, die er selbst im Haupt-Thread Pretext gegenüberstellte.
Das allgemeine Muster des Ökosystems: ein sehr kleiner Kern, den viele auf Sprachen (Swift, C#, Dart, Python), Frameworks (React, React Native, Flutter, Vue, Vite, Unity) und Nischenanwendungsfälle (PDF, Video, 3D) erweitern, plus eine Schicht von „Skills” für KI-Agenten.
Zahlen zum Repository
Messung: 22. August 2026, GitHub-API und npm-Registry.
| Metrik | Wert |
|---|---|
| Sterne | 49.966 |
| Forks | 2.729 |
| Echte Abonnenten | 147 |
Commits (main-Branch) | 410 |
| Offene Issues + PRs | 90 |
| Hauptsprache | TypeScript |
| Lizenz | MIT |
| Erstellung | 7. März 2026 |
| Neueste npm-Version | 0.0.8 (12. Juni 2026) |
| npm-Downloads (Woche 14.–20. Aug. 2026) | 905.501 |
| npm-Downloads (Monat 22. Jul.–20. Aug. 2026) | 4.127.107 |
watchers_count spiegelt die Sternezahl, weshalb subscribers_count als tatsächliche Abonnentenzahl gemeldet wird. open_issues_count umfasst offene Änderungsanfragen. Die Releases-API lieferte eine leere Liste: Pretext veröffentlicht keine formalen GitHub-Releases, hat aber Git-Tags (v0.0.4…v0.0.8) und npm-Versionen mit einem CHANGELOG.md pro Version; die Referenzversion ist die von npm (0.0.8).
Die wichtigsten Mitwirkenden nach Beitragszahl sind chenglou (403), bg-l2norm (2) und, mit je einem Beitrag, brandonmcconnell, cxa, threepointone, bytaesu und somnai-dreams. Die Konzentration von 403 der 410 Beiträge bei einem einzigen Autor bestätigt, dass es sich um ein Projekt mit einem einzigen Hauptverantwortlichen handelt.
Schnelleinstieg
Installation und erster Start
npm install @chenglou/pretext
Anforderungen: eine Browserumgebung (oder Runtime) mit verfügbarem Intl.Segmenter und Canvas 2D. Reines Node ohne diese APIs wird derzeit nicht unterstützt; serverseitiges Rendering ist als zukünftige Arbeit aufgeführt. Es ist ausschließlich ESM; es gibt keine direkte Unterstützung für CommonJS-require().
Erster Start im Browser:
import { prepare, layout } from '@chenglou/pretext'
const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')
const { height, lineCount } = layout(prepared, 320, 20)
// height und lineCount: reine Arithmetik, ohne DOM-Layout oder Reflow
Gängige Arbeitsabläufe
- Die Höhe eines Absatzes vor dem Rendern vorhersagen.
prepare(text, '16px Inter')einmal;layout(prepared, breite, 20)so oft wie sich die Breite ändert. Das Ergebnis liefert{ height, lineCount }, um den Scroll zu verankern, eine virtualisierte Zeile zu dimensionieren oder zu prüfen, dass ein Etikett in eine Schaltfläche passt. - Text um ein Bild herum fließen lassen (redaktionelles Layout). Mit
prepareWithSegmentsplus einemLayoutCursorpro ZeilelayoutNextLineRange()aufrufen mit einer Breite, die schrumpft, während die Zeile neben dem Bild liegt, undmaterializeLineRange(), um den Text dieser Zeile zu erhalten. - Mehrzeiliges Shrinkwrap (die Mindestbreite, die den Text enthält).
measureLineStats(prepared, breite)liefert{ lineCount, maxLineWidth };walkLineRanges()durchläuft die Zeilen, ohne Strings zu erstellen — nützlich für eine binäre Suche nach einer „schönen” Breite. - Chat-Virtualisierung mit TanStack Virtual.
prepare()pro Text und Stil zwischenspeichern,layout()für die aktuelle Breite ausführen und, wenn sich Breite/Schriftart/Zeilenhöhe ändern, die Messungen von Virtual zurücksetzen, um Offsets neu zu berechnen.
Wesentliche Konfiguration
Die 4–5 „Einstellungen”, auf die ein neuer Nutzer zuerst stößt, sind die Optionen von prepare() und die Parameter von layout(): font (ein Canvas-Schriftstring, z. B. 16px Inter, der mit dem effektiven CSS des gemessenen Texts übereinstimmen muss — eine benannte Schriftart verwenden, nicht system-ui), lineHeight (ein layout()-Parameter, der mit dem CSS line-height übereinstimmen muss), { whiteSpace: 'pre-wrap' } (für textarea-ähnlichen Text), { wordBreak: 'keep-all' } (für CJK/Hangul) und { letterSpacing: n } (ein Wert in CSS-Pixeln).
Zudem gibt es zwei globale Helfer: setLocale(locale?), um das Gebietsschema des Wortsegmentierers festzulegen (und Caches zu leeren), und clearCache(), um den gemeinsamen Metrik-Cache freizugeben, wenn die App durch viele Schriftarten zirkuliert.
Häufige Fallstricke und Lösungen
system-uiist unter macOS unsicher. Canvas und DOM können unterschiedliche Schriftarten auflösen. Lösung: eine benannte Schriftart verwenden.PLATFORM_BUGS.mdverlinkt die Bugs Chromium #489579956 und Mozilla #2020917.- Apple-Color-Emoji werden in Canvas bei kleinen Größen größer gemessen als im DOM (macOS, Chrome und Firefox). Die Korrektur wird einmal pro Schriftart per Fähigkeitserkennung erkannt und pro Emoji-Graphem abgezogen; ihre Deaktivierung senkt den Genauigkeits-Sweep von 7680/7680 auf ~7652–7660/7680.
- Warten, bis die Schriftart geladen ist, bevor vorbereitet wird. Ist die Schriftart nicht verfügbar, weichen Canvas-Messungen von dem ab, was der Browser später anwendet.
layout()mit leerem String liefert{ lineCount: 0, height: 0 }. Wird ein anderes Verhalten benötigt, mitMath.max(1, lineCount) * lineHeightklemmen.prepare()nicht ohne Änderungen erneut aufrufen. Das zerstört den Hauptvorteil der Vorberechnung; bei einer Größenänderung wird nurlayout()erneut ausgeführt.- Safari benötigt eine Zeilenumbruch-Toleranz von 1/64 px (Chromium/Gecko nutzen 0,005 px). Und Safari 26.4 scheitert noch an
word-break-keep-all-006von WPT; die KorrekturbreakKeepAllAfterPunctuationbleibt bestehen, bis WebKit es upstream behebt. - Headless mit
devicePixelRatio = 1verschleiert die Emoji- und macOS-system-ui-Bugs. In einem Browser mit Kopf auf einem Retina-Display erneut testen. - Automatische Silbentrennung ist nicht eingebaut. Weiche Trennstriche vor
prepare()einfügen. - CSS außerhalb der
canvas.font-Abkürzung (font-optical-sizing,font-feature-settings,font-variation-settings) wird nicht separat modelliert.
Integrationen und Migration
- TanStack Virtual: offiziell dokumentierte Integration als Höhenschätzer für textdominierte Zeilen. TanStack behält weiterhin Scroll, Bereich und Positionierung; Pretext liefert nur die Schätzung.
- Migration von DOM-Messungen: Das Migrationsmuster ist,
getBoundingClientRect()/offsetHeightauf dem heißen Pfad durchprepare()+layout()zu ersetzen, während der echte Text im DOM für die Barrierefreiheit erhalten bleibt. - Migration von uWrap.js (leeoniya): uWrap ist ~2 KB groß, nur ASCII/Latein, nur
white-space: pre-line, ohne weiche Trennstriche oder Emoji; Pretext decktnormalundpre-wrap, weiche Trennstriche, Emoji und vollständige Mehrzeiligkeit ab. Es ist eine Umfangsänderung, keine API-Änderung. - Integration mit MCP/CI/Editoren: eine Entwicklungszeit-Nutzung (prüfen, dass ein Etikett ohne Browser passt) und CI-Fälle (Geometrie als Unit-Test), SSR (vorberechnete Höhen bei der Hydration) und 3D/WebGL (Zeilenpositionen als Koordinaten). Es ist kein offizieller Pretext-MCP-Server dokumentiert.
Wie man beiträgt
Der Entwicklungsprozess ist in DEVELOPMENT.md und AGENTS.md dokumentiert: einmalige Installation mit bun install (das Projekt nutzt Bun, nicht npm, für die Entwicklung); tägliche Entwicklung mit bun start (bedient die lokale Demo-Website unter http://localhost:3000); Verifizierung mit bun run check (Typprüfung mit tsc, Linting mit oxlint, Dead-Code-Scan mit knip) und bun test; Pretext-spezifische Genauigkeit und Benchmark (bun run accuracy-check, accuracy-snapshot, benchmark-check, corpus-check/corpus-sweep); Paketierung mit bun run build:package.
Dokumentierte Regeln: das README als öffentliche Wahrheitsquelle pflegen; kein Monkey-Patching (die Grundursache beheben, nicht das Symptom); das Changelog trägt nur nutzerorientierte Notizen; Diffs, die die heiße Engine ändern, müssen die Genauigkeits- und Benchmark-Snapshots neu generieren.
Wie die Community reagierte
Die zurückgewonnene Evidenz zeigt starke Begeisterung, aber auch konkrete Kritik an der Leistung und daran, worauf die Leute achten.
Der Haupt-Hacker-News-Thread (397 Punkte, 69 Kommentare, veröffentlicht am 28. März 2026) sammelte bemerkenswerte Meinungen. simonw: „Dieses Ding ist sehr beeindruckend. Das Problem, das es löst, ist die effiziente Berechnung der Höhe von umbrochenem Text auf einer Webseite, ohne diesen Text zuerst zu rendern (sehr teuer). Es tut dies, indem es die Breite/Höhe einzelner Segmente — man denke an Wörter — vorberechnet und zwischenspeichert…” rattray: „Unabhängig vom Thema sind die Ankündigungs-Tweets dazu eine meisterhafte Demonstration dafür, warum eine architektonische/Plattform-Verbesserung hohe Wirkung haben kann.”
leeoniya (Autor von uWrap.js) löste den technischsten Austausch aus: „Ich habe vor einem Jahr etwas Ähnliches für diesen Zweck geschrieben, aber viel einfacher und 2 KB, keine KI: uWrap.js… Bei ASCII-Text ist meins in 80 ms fertig, während Pretext 2200 ms braucht.” simonw antwortete, dass uWrap nur Latein handhabe und keine weichen Trennstriche/Emoji, und nur pre-line. liuliu (ein Projektmitarbeiter) entgegnete, dass prepare measureText in einer Schleife nutze und dass „diese Bibliothek dafür gedacht ist, prepare einmal und layout viele Male auszuführen. layout-Aufrufe sollten unter 1 ms liegen.” leeoniya probierte, 100.000 Sätze mit Zeilenumbrüchen zu verketten: „nicht viel schneller, ~1880 ms.”
lewisjoe: „Kurze Zusammenfassung von pretext: Wenn man Text im Web layouten will, muss man die canvas.measureText-API nutzen und Umbruch/Segmentierung/RTL selbst implementieren. Pretext macht das einfacher.” rikroots: „Textlayout-Engines sind absurd schwierig. Man beginnt zu denken, ‘es ist eine schwere Aufgabe, aber ich schaffe das’ und findet sich drei Monate später in einer Ecke wieder, schreiend ‘warum, Chinesisch?’” tadfisher (von Mozilla): „Ich würde es begrüßen, wenn das Offenlegen des Textlayout-Messers des Browsers eines Tages zu einer Web-API würde.”
In einem sekundären Thread (16 Punkte) wandte sublinear ein: „So cool das ist, fällt es mir schwer, das auf einer Produktions-Webseite zu sehen. Wenn es eine JS-Abhängigkeit für das Styling gibt, muss der Entwickler trotzdem ein CSS-Fallback schreiben.” In einem anderen Thread (14 Punkte, 5 Kommentare) korrigierte lewisjoe einen Artikel über Pretext: „Pretext befreit das Browser-Textlayout nicht vollständig (zumindest noch nicht). Es nutzt weiterhin canvas.measureText, das die kritische Schwerarbeit erledigt”; der Autor des Artikels, cyrusradfar, stimmte zu und aktualisierte den Beitrag.
Simon Willisons Blog (29. März 2026) präsentiert es als „eine aufregende neue Browser-Bibliothek” und hebt die Verifizierungsmethode mit Der große Gatsby und die mehrsprachigen Korpora hervor. Den Odells Blog (30. März 2026, Dev.to) argumentiert, dass „die Community drei Tage damit verbracht hat, Drachen zu bauen [Canvas-Demos]. Sie sollte Chat-Oberflächen bauen” — das eigentliche Merkmal sei, seiner Ansicht nach, die Höhe vorherzusagen, ohne aus dem DOM zu lesen.
Ehrliche Zusammenfassung: Die Begeisterung ist breit und auf hohem Niveau (397 Punkte im Haupt-Thread). Die eigentliche Kritik kommt von leeoniya (Leistung von prepare in einer Schleife) und sublinear (Schwierigkeit der Produktionsadoption wegen der JS-Abhängigkeit für Styling). cyrusradfar selbst räumt ein, dass die SSR-Einschränkung noch von Canvas abhängt.
Pretext im Vergleich zu anderen Ansätzen
| Ansatz | Überprüfbare Überschneidung | Überprüfbarer Unterschied |
|---|---|---|
leeoniya / uWrap.js | Schätzt Zeilenhöhe für Virtualisierung mit Canvas’ measureText. | uWrap ist ~2 KB groß, nur Latein/ASCII, nur white-space: pre-line, ohne weiche Trennstriche oder Emoji; Pretext deckt normal und pre-wrap, weiche Trennstriche, Emoji und vollständige Mehrzeiligkeit ab. |
| Skia-wasm (auf HN erwähnt) | Rendert Text, ohne vom Browser-DOM abhängig zu sein. | Skia ist eine vollständige Rendering-Engine, die „die ganze Welt mitbringt”; Pretext misst und verteilt nur, delegiert das finale Rendering an den Browser. |
DOM-Messungen (getBoundingClientRect, offsetHeight) | Liefern die reale, endgültige Geometrie. | Erzwingen synchronisierten Reflow; bei großen Listen erzeugen sie Layout-Thrashing. Pretext vermeidet diesen Lesevorgang auf dem heißen Pfad. |
CSS text-wrap: balance/pretty (auf HN erwähnt) | Passt die Anzahl der Wörter pro Zeile an. | Eliminiert nicht den leeren Raum am rechten Rand und liefert keine Höhe vor dem Rendern; es ist eine Ergänzung, kein Ersatz. |
Der nützlichste Vergleich erfolgt nicht nach Popularität: Pretext sticht hervor, wenn wiederholte Messung auf dem kritischen Pfad liegt oder wenn die App die Zeilenumbrüche explizit besitzen muss. Für eine gewöhnliche Website mit stabilem Inhalt bleiben CSS, ResizeObserver und semantische Struktur einfacher und angemessener.
Anwendungsfälle und wem dieses Repository helfen kann
- Teams, die textdichte Listen virtualisieren (Chats, Feeds, Kommentare, Benachrichtigungen, Zeitleisten) können
prepare()+layout()mit TanStack Virtual nutzen, um die Höhe jeder Zeile vorherzusagen und den Scroll ohne sichtbare Korrekturen zu verankern. - Ersteller von Rich-Text-Editoren oder streamendem KI-Chat können Höhen neu berechnen, während Tokens eintreffen, ohne dass eine sich verändernde Blase den Bildlauf ständig korrigiert.
- Canvas-, SVG-, WebGL- oder 3D-Engine-Entwickler können Zeilen und Bereiche erhalten, um Text in einem DOM-losen Renderer zu zeichnen, oder Zeilenpositionen als Koordinaten und Texturgröße berechnen, bevor GPU-Speicher zugewiesen wird.
- SSR-/Hydration-Teams können Höhen während des serverseitigen Renderns vorberechnen, um den Client vom ersten Frame an mit korrekten Dimensionen zu hydrieren und CLS zu vermeiden.
- Wer Oberflächenvalidierung während der Entwicklung durchführt, kann prüfen, dass ein Etikett in eine Schaltfläche passt oder ein 50-Zeichen-Text auf eine Karte passt, ohne den Browser zu öffnen.
- Plattformübergreifende Teams können vom Kern ausgehen und verifizierte Ports nutzen: Swift, React Native, Flutter, C#/SkiaSharp oder Python.
- Für eine gewöhnliche Website mit stabilem Inhalt bleiben CSS +
ResizeObserver+ semantische Struktur einfacher und angemessener.
Ressourcen
- Repository: https://github.com/chenglou/pretext
- Dokumentation / Demos: https://chenglou.me/pretext/
- npm-Paket: https://www.npmjs.com/package/@chenglou/pretext (nur ESM, 0.0.8)
- Entwicklungsleitfaden: https://github.com/chenglou/pretext/blob/main/DEVELOPMENT.md
- Plattform-Bug-Register: https://github.com/chenglou/pretext/blob/main/PLATFORM_BUGS.md
- TanStack Virtual (offizielle Integration): https://tanstack.com/virtual/latest/docs/pretext
- Kuratierte Liste: https://github.com/bluedusk/awesome-pretext
Hinweis: Dieser Artikel kombiniert das README, DEVELOPMENT.md, PLATFORM_BUGS.md, das CHANGELOG.md, die npm-Registry @chenglou/pretext, die GitHub-API und Artikel von Simon Willison, Den Odell und Cyrus Radfar, alle konsultiert am 22. August 2026. Stern-, Download- und Beitragszahlen ändern sich mit der Zeit.
Kommentare