[HN Gopher] Pretext: TypeScript library for multiline text measu...
___________________________________________________________________
Pretext: TypeScript library for multiline text measurement and
layout
https://x.com/_chenglou/status/2037713766205608234,
https://xcancel.com/_chenglou/status/2037713766205608234 Demos:
https://chenglou.me/pretext/, https://somnai-
dreams.github.io/pretext-demos/
https://kevinho.com/experiments/biomap/
Author : emersonmacro
Score : 164 points
Date : 2026-03-28 16:52 UTC (1 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| rattray wrote:
| Regardless of the subject matter, the tweets announcing this are
| a masterclass in demoing why an architectural/platform
| improvement can be impactful.
| rattray wrote:
| Some details on how it works from a code comment:
|
| Problem: DOM-based text measurement (getBoundingClientRect,
| offsetHeight) forces synchronous layout reflow. When components
| independently measure text, each measurement triggers a reflow of
| the entire document. This creates read/write interleaving that
| can cost 30ms+ per frame for 500 text blocks.
|
| Solution: two-phase measurement centered around canvas
| measureText.
|
| prepare(text, font) -- segments text via Intl.Segmenter, measures
| each word via canvas, caches widths, and does one cached DOM
| calibration read per font when emoji correction is needed. Call
| once when text first appears.
|
| layout(prepared, maxWidth, lineHeight) -- walks cached word
| widths with pure arithmetic to count lines and compute height.
| Call on every resize. ~0.0002ms per text.
|
| https://github.com/chenglou/pretext/blob/main/src/layout.ts
| mgaunard wrote:
| What about hyphenization?
| simonw wrote:
| That's in there too: https://github.com/chenglou/pretext/blob
| /53a065b8a345fc29831...
| gastonmorixe wrote:
| Has someone ever found a good solution for long / infinite lists
| / grids virtualization not breaking browsers native text search?
|
| Maybe for this we need a new web "Search" API instead of JS. Not
| sure it can be done otherwise without browser's help.
| dalmo3 wrote:
| This is awesome! I had this problem when building a datagrid
| where cells would dynamically render textarea. IIRC I ended up
| doing a simple canvas measurement, but I had all the text and
| font properties static, and even then it was hellish to get it
| right.
| rpastuszak wrote:
| Love this. I especially liked shape based reflow example.
|
| This is something I've been thinking for ages and would love to
| add to Enso (enso.sonnet.io), purely because it would allow me to
| apply better caret transitions between the lines of text.
|
| (I'm not gonna do that because I'm trying to keep it simple, but
| it's a strong temptation)
|
| Now a CSS tangent: regarding the accordion example from the site
| (https://chenglou.me/pretext/accordion), this can be solved with
| pure CSS (and then perhaps a JS fallback) using the `interpolate-
| size` property.
|
| https://www.joshwcomeau.com/snippets/html/interpolate-size/
|
| Regarding the text bubbles problem
| (https://chenglou.me/pretext/bubbles), you can use `text-wrap:
| balance | pretty` to achieve the same result.
|
| (`balance` IIRC evens out the # of lines)
| lewisjoe wrote:
| Quick overview of pretext: if you want to layout text on the web,
| you have to use canvas.measureText API and implement line-
| breaking / segmentation / RTL yourself.
|
| Pretext makes this easier. Just pass the text and text properties
| (font, color, size, etc) into a pure JS API and it layouts the
| content into given viewport dimension.
|
| Earlier you'll have to either use measureText or ship harbuzz to
| browser somehow. I guess pretext is not a technical breakthrough,
| just the right things assembled to make layouting as a pure JS
| API.
|
| I have one question though: how is this different from Skia-wasm
| / Canvaskit? Skia already has sophisticated API to layout
| multiline text and it also is a pure algorithmic API.
| lewisjoe wrote:
| If the author is right, this is going to be huge for GUI web
| frameworks and for future rich text editors.
| madeofpalk wrote:
| > how is this different from Skia-wasm
|
| It's not wasm?
| simonw wrote:
| This thing is _very_ impressive.
|
| The problem it solves is efficiently calculating the height of
| some wrapped text on a web page, without actually rendering that
| text to the page first (very expensive).
|
| It does that by pre-calculating the width/height of individual
| segments - think words - and caching those. Then it implements
| the full algorithm for how browsers construct text strings by
| line-wrapping those segments using custom code.
|
| This is absurdly hard because of the many different types of
| wrapping and characters (hyphenation, emoji, Chinese, etc) that
| need to be taken into account - plus the fact that different
| browsers (in particular Safari) have slight differences in their
| rendering algorithms.
|
| It tests the resulting library against real browsers using a wide
| variety of long text documents, see
| https://github.com/chenglou/pretext/tree/main/corpora and
| https://github.com/chenglou/pretext/blob/main/pages/accuracy...
| jimkleiber wrote:
| I had struggled so much to measure text and number of lines
| when creating dynamic subtitles for remotion videos, not sure
| if it was my incompetence or a complexity with the DOM itself.
| I feel hopeful this will make it much easier :-)
| rikroots wrote:
| > This thing is very impressive.
|
| Agreed! Text layout engines are stupidly hard. You start out
| thinking "It's a hard task, but I can do it" and then 3 months
| later you find yourself in a corner screaming "Why, Chinese?
| Why do you need to rotate your punctuation differently when you
| render in columns??"
|
| This effort feeds back to the DOM, making it far more useful
| than my efforts which are confined to rendering multiline text
| on a canvas - for example:
| https://scrawl-v8.rikweb.org.uk/demo/canvas-206.html
| TacticalCoder wrote:
| > The problem it solves is efficiently calculating the height
| of some wrapped text on a web page, without actually rendering
| that text to the page first (very expensive).
|
| But in the end, in a browser, the actual text rendering is
| still done by the browser?
|
| It's a library that allows to "do stuff" before the browser
| renders the actual text, but by still having the browser
| render, eventually, the actual text?
|
| Or is this thing actually doing the final rendering of the text
| too?
| simonw wrote:
| Yes the browser still renders the text at the end - but you
| can now do fancy calculations in advance to decide where
| you're going to ask the browser to draw it.
| Trufa wrote:
| I said it elsewhere but will repeat it here:
|
| This is incredibly impressive, many of this things have been
| missing for forever! I remember the first time I couldn't figure
| out how do a proper responsive accordion, it was with bootstrap
| 1, released in 2011 !! Today it's still not properly solved
| (until now?).
|
| Many of thing things belong in css no in js, but this has been
| the pattern with so many things in the web
|
| 1) web needs evolve into more complex needs 2) hacky js/css
| implementation and workarounds 3) gets implemented as css
| standard
|
| This is a not so hacky step 2. Really impressive,
|
| I would have thunk that if this was actually possible someone
| would have done it already, apparently not, at some point I
| really want to understand what's the real insight in the library,
| their https://github.com/chenglou/pretext/blob/main/RESEARCH.md
| is interesting, they seem to have just done the hard work, of
| browser discrepancies to the last detail of what does an emoji
| measure in each browser, hope this is not a maintenance
| nightmare.
|
| All in all this will push the web forward no doubt.
| staminade wrote:
| Responsive accordions are actually solved using CSS nowadays,
| but plenty of other things aren't, and the web has definitely
| needed an API or library like this for a long, long time. So
| it's great that we now have it.
|
| Building something like this was certainly _possible_ before,
| but it was a lot of effort. What 's changed is simple: AI. It
| seems clear this library was mostly built in Cursor using an
| agent. That's not a criticism, it's a perfect use of AI to
| build something that we couldn't before.
| c-smile wrote:
| Yeah, that's definitely needed.
|
| That's why I've added Graphics.Text
| (https://docs.sciter.com/docs/Graphics/Text) in Sciter.
|
| Graphics.Text is basically a detached <p> element that can be
| rendered on canvas with all CSS bells and whistles.
| lateforwork wrote:
| This should be standard functionality offered by browsers. How do
| you make feature requests to W3C, and do they allow the community
| to vote on feature ideas?
| siriusfeynman wrote:
| I've had to approximate text size without rendering it a few
| times and it's always been awkward, I'm glad there's something to
| reach for now (just hoping I remember that this exists next time
| I need it)
| gjvc wrote:
| only took 30+ years to get (back) to this point.
|
| wasted generation.
___________________________________________________________________
(page generated 2026-03-29 23:00 UTC)