This Should be Illegal: Making a Layout Engine Faster Than the Browser Itself -- In JavaScript
But I’ve done it anyway.
Let me be precise about what I am claiming, because the claim is large.
Browser layout engines are smoking fast. They are written in C++. They have been optimized by the best engineers for decades. They handle every writing system on earth. They can do anything imaginable -- except making coffee.
Still, my engine beats them. Runs circles around them. Every bit as capable as them. Solves even more layout problems than them.
In pure JavaScript.
No WebAssembly. No native bindings.
Just JavaScript.
It doesn’t make coffee yet. But if you are nice, you will buy one for me because I’m giving you my engine for free.
Let me tell you how I did it, and why it matters now more than ever.
What Kind of Wizardry Is This?
Let the numbers speak.
All-capabilities fixture. Eight pages of everything at once -- multilingual text, inline objects, tables, images, BIDI, hyphenation, mixed scripts, baseline alignment across CJK and Latin. The hardest general layout fixture I could construct. Layoutmaster: 15.74ms total. That’s less than 2ms per page, or 500 pages in a second. The browser? 16.58ms. That is pure JavaScript matching a C++ engine on its most comprehensive home turf. Not cherry-picked edge cases. Not toy samples.
Complex table pagination. Eight pages of tables with colSpan, rowSpan, repeated headers, and forced page breaks -- the kind of thing that makes most layout systems quietly give up. Layoutmaster: 5.66ms. DOM: 16.70ms. Three times faster.
Flow through 30 variable regions. A multilingual story flowing through 30 differently-sized, differently-styled containers. 7,186 characters placed across 350 pieces. Layoutmaster: 28.56ms. DOM: 34.76ms — and 297 binary-search reads to get there. The DOM does not know what fits. It guesses, checks, adjusts, guesses again, 297 times, to approximate an answer Layoutmaster solved in a single pass.
Then run it again. Layoutmaster: 0.02ms. DOM: 34.76ms. Because once Layoutmaster has solved a world, it remembers. The DOM starts from scratch every time, 297 guesses and all.
But Why Bother?
I hear you: The browser seems capable enough. Why reinvent the wheel?
Because reinventing the wheel is what we software engineers love to do, and also because we are headed into to a new era -- an era of AI, of generative frontends that are unpredictable, volatile, chaotic. In other words, layouts that never stop negotiating.
That is the Achilles heel for the mighty browser.
The browser always maintain a complex data structure called DOM. Layout is constructed by walking the DOM. When something changes, the browser has to rebuild the DOM so it can give you the updated layout.
Do this too often and too fast, you cause the infamous layout thrashing. Performance and user experience will suffer, and the browser may even collapse.
I experienced this first hand:
To stress-testing my engine, I built a masonry wall of 304 cards in varying heights. Each card contains one of the 76 chapters of an 80,000-word novel in 4 variations. That’s 320,000 words creating a massive wall of text 193,000 pixels tall.
Layoutmaster did it in 475ms without breaking a sweat. Then I tried the same thing with the browser. It took JavaScript 182.3ms to “handoff” the layout changes to DOM, then the browser finished and settled the layout in 4289.0ms.
That turned into a moment of crisis. Yes the master is 10 times faster. Yes you only need a single produce() call instead of hundreds... But 4 seconds isn’t too shabby at all, and it’s not like you will encounter a 50-story-tall masonry wall every day. I suddenly find myself questioning the justification of my engine’s very existence.
Then I let my hand slip. I accidentally dragged the border of the browser window --
The grid went into a frenzy -- Texts marched across surface like armies of ants. Cards shuffled like they were in the hands of a dealer behind a gambling table. I dragged it a little more, and the parade just wouldn’t stop until a full 30 seconds later!
There you have it -- the “Why.” My 50-story-tall masonry wall may not have been the norm even a year ago, but I’m betting you a cup of coffee it won’t look so odd in the coming age of AI generated contents and interactions.
The browser needs help, big help.
The Solution
Make a layout engine that’s as fast as the browser, as capable as the browser, and plays nicely with the browser. Then you relieve the browser from its layout duties so it only needs to paint the layout-ready content.
The catch? You won’t find many solutions like that, if at all.
Layout, being a fundamental substrate of computing, is also one of the hardest, boringest. That’s why when the browser offered an easy exit, everyone embraced it and never looked back.
That’s also why you won’t find many lying around on GitHub.
And even fewer ones that can run as fast, if not faster, than the browser. Ones that can be as capable as the browser. Ones that can play nicely with the browser. Am I repeating myself? Yes, that’s the whole point.
Enter Layoutmaster.
It is a 250K library written in pure Javascript. It features six simplistic, stateless API calls:
form() — given width, how does this lay out, and how tall does it get?
fit() — given bounded space, what fits, and what remains?
flow() — given a series of bounded spaces and content that overflows, where does it continue?
pour() — given a shape instead of a rectangle, fill it.
produce() — give me publishing-grade pages.
plan() — given repeated intent, solve it without starting over.
Simple they may seem, but these six verbs solve a world of complex layout challenges and unlock endless possibilities -- all without touching the browser’s DOM.
Don’t mistake this with toys that absurdly claim to be 600 times faster than DOM and yet all they do is measuring the height. You don’t build a house with only a ruler.
Layoutmaster is the real deal. It’s the bulldozer. It’s the forklift. It’s the construction crew. It can literally give you the house.
Each of the six APIs return you a collection of solved layout “pieces”. They are like job tickets coming out of a foreman’s clipboard: board A goes here, cut to this size, nail it at this mark. Give those tickets to a basic-but-careful crew and you get the house.
In UI terms, that crew might be HTML spans, canvas fillText(), SVG text, WebGL glyphs, or a native view. And the “house” is your beautifully formatted page.
So What’s the Secret?
You still reading?
Your patience shall be rewarded. So here is my secret.
Traditional layout engines see text as a one-dimensional problem. Characters flow left to right, lines stack top to bottom, blocks nest inside blocks. The logic governing all of this is a tangled web of conditionals.
The browser has optimized the hell out of it. There is little room to improve. And even if there is, it’s out of reach for a pure Javascript engine.
The only way to beat it is to not play that same game. It requires a different perspective:
That a layout problem is indeed a collision problem.
It’s like a video game -- Actors occupy the same space, negotiating positions through physical displacement. Game engines solve that thousands of times per frame without breaking a sweat.
Once you see that connection, you can’t unsee it.
Text wrapping around an image is collision. Multi-column flow is constrained spatial traversal. Pagination is world partitioning across viewport slices. An exclusion zone is terrain. A table of contents that needs to know its own page numbers before it exists is just a reactive signal chain — something game engines handle through actor messaging, not multiple rendering passes.
Every layout problem, reframed as a spatial simulation problem, already had a solution. A better solution than anything the typesetting world had come up with. Because game engines had been solving these problems under far more demanding conditions -- real-time, deterministic, at 60 frames per second -- for decades.
The simulation model is different at the root. Actors inhabit a world. They have geometries. They negotiate space through physics. The engine maintains state, updates locally, classifies changes into tiers -- some cost nothing, some cost almost nothing, some require targeted resettlement from the affected frontier and nothing more. The system does not recompute what it already knows. It cannot, by design.
That structural efficiency is the key. Not because JavaScript got faster. Because the work being done is fundamentally, architecturally different.
And that -- is the master’s dirty little secret.
If you found this useful -- you know where the coffee shops are.
Layoutmaster is open source and can be found at cosmiciron.github.io/layoutmaster.
The npm package is @layoutmaster/layoutmaster.



