Unfortunately the author is not only correct about front end development vibes, but due to this state of affairs, I ceased to recognize browser based UIs as being software development at all. Too much browser tech is broken to call it software. As for agents, good for them!
It scores well here because Astro is for “content-driven websites” and that’s what the benchmark app was. I’d be curious how different the results would be if the app was highly interactive, with nontrivial realtime/async stuff going on etc.
And then you just use your favorite js framework with Astro and it will still be good. I use Astro with react and heroui a lot. Since the latter does not need any js for many components anymore you still get zero js builds unless you actually need interactivity.
Agreed. Go with solidstart (who just released a big V2 upgrade a few months back) if you want an extremely elegant solution to async, error handling and heavily concurrent behaviors.
Very easy to setup and way more readable than the equivalent React code.
But is zero client side JS necessarily better? I prefer the progressive enhancement philosophy of SvelteKit. When your internet connection and browser does support JS, it makes for a faster user experience.
When I was running a small dev agency with a sprinkling of web projects, Angular was useful because it every project looked more or less the same. The rigidity (and verbosity) it imposed was an advantage in this setting, as it helped with the cognitive load when switching between projects. Apart from that, I wasn’t a fan either.
Angular is an absolute joy to work with as a framework, improving year after years, not scared of shifting heavily when a new favorable paradigm comes in. You never had data to prove that angular sucks because all the benchmarks don't say so.
Just use plain HTML for God's sake. HN demonstrates very well that you can do plenty without some Javascript monstrosity. At the very least, make your your websites degrades gracefully when JS is turned off.
"do plenty" or just use React for everything and have a single thing where you don't need to worry about the limitations or having to remake the same stuff the framework provides?
> At the very least, make your your websites degrades gracefully when JS is turned off.
I have noped out of so many sites that are - or should only be - serving simple content when I see the "please enable JavaScript" notice or site just plain breaks. It's so disappointing and irritating.
I really have no idea where comments like yours come from. I‘m baffled each time I read it. You must be really, really far removed from any commercial browser development process.
I really have no idea where comments like yours come from. I‘m baffled each time I read it. You must be really, really far removed from any commercial browser development process.
This benchmark is too simplified to be meaningful. The choice of a framework is rarely based on speed alone, it factors in other elements like the user's domain knowledge, long term maintainability and the framework's track record itself w.r.t security and development of features.
In this regard alone, it will make a lot of sense to spend extra $2 and 2 mins to trade off for a long-term maintainable codebase and code you can reason about than just something made quickly just to get it deployed fast.
In my personal use case, that would be Svelte 5 for me and I'm sure it will be something else for everyone.
It's also used on a dead simple app. These comparisons are almost always using apps no more complicated than to do apps, which is lightyears removed from actual commercial products
Now that IE is dead and most of the cross-platform implementation differences have been fixed, you are generally better off with vanilla JS instead of jQuery.
The vanilla advantage is also there in a pure client-side pwa. Arguably it’s even bigger, because the bundle size ends up way smaller and the agent needs to hold less in context.
Plus all the other vanilla advantages: fewer dependencies, lower maintenance, less retraining, etc…
They also were unnecessary even before AI, the biggest advantage of React over HTMX-style apps was that you could recruit someone more easily but the SPA complexity wasn't worth it and it scaled terribly.
Now that you don't write the code now, I don't see why I would pick React style libraries unless the codebase is already there.
We just write different stuff. For content driven websites you can skip js frameworks altogether. For web apps it would not be a good idea.
It's all about how much interactivity you need. A lot of business web apps are full featured commercial software packed in SPA form. You will need a lot of stuff client side and without framework it will be a mess. Unless you write framework yourself but the you are reinventing a wheel.
The whole reason for switching from server-side to SPAs and frameworks was increasing responsiveness for users, better transitions, and allowing optimistic updating.
All of these thing still matter no matter what you are coding with.
In typical HN style, you are both pretentious and wrong. Javascript frameworks save you the complexity of an agent holding the entire library code in their context. For example, an agent can work with 2-4 react components for a current ticket without needing to know each line of internal React code.
Divide the amount of revenue from the big AI companies by the total number of developers worldwide and you'll see that most are still mostly hand-coding despite what the megaphones on the internet say.
The overwhelming majority AI spend is being done by startups funded by venture capital.
Meanwhile, big companies have massively cut/capped AI spending at the exact time these companies need to triple prices to get any margins at all.
Perhaps dead internet theory applies more than normal to programming forums.
I mean it just seems like even in the agentic era, you should know when to use the right tool for the right job. The site shown seems perfect for htmx style websites, so idk why you would use an SPA. Still very cool experiment, appreciate the data and human writing!
> My goal here is not to write the end-all-be-all benchmark for “I’m a vibe-coder, which framework should I choose?” The point of this post is to demonstrate that it’s possible in the era of AI coding to still make decisions based on evidence rather than vibes.
But it’s obvious that the article will be understood as a useful benchmark, so author probably should have addressed that point earlier and more thoroughly.
Taking the authors pov for a moment, they just showed you how to put all your criticisms to work in making a newer better benchmark :)
I have most of my apps in it without much trouble.
One of my recent ones had a very complicated form and state management.
AI really struggled with HTMX in that use case.
Like the form might work but the page would take 30s to load. Or some state would randomly drop or a toggle wouldn't work after changing a dependency.
If I rewrote that in react it would have one shot it without a doubt. Some things are just better models for different problems.
For the record I eventually got enough tests in place to keep the agent honest and the HTMX version is now a lot faster anything I could have got out of react but yeah, it was an adventure.
I judge languages by how they look. JavaScript is a wall of const/async/await these days, which is ugly. Functionality aside, the APIs have gotten pretty decent. The language has gotten uglier. It used to be nice and nuanced even with boilerplate. Closures and prototype inheritance is neat. Walls of const are not. Does every enclosed function need a million consts for every expression?
Async JavaScript using callbacks had a learning curve, but once you learned how to contain it and treat callback indentation as an opportunity to refactor it felt similar to coding in lisp.
The problem was the learning curve, and the fact you had to rewire your brain a bit compared to coding in something procedural.
Yes, I keep saying this. Async await is like loading spinners - a fix for a problem that shouldn't exist in the first place.
As much as possible should be happening locally, synchronously on the computer, in-process, or at least without yielding your thread context (and even then there are things like page faults which async/await wont save you from, they are 'invisible' to a regular developer).
While you might dismiss this idea, page faults used to be THE leading cause of delays back when hard drives were the norm.
That JS supports await isn't nearly as much a problem as the fact that it defensively defers execution any time it encounters one.
This hurts most badly for iterators.
Files are usually read from disks in chunks of 64K bytes. If you present the data as an async byte iterator you'll get 65,534 defensive deferrals, and one actual wait.
Of you have ten layers of transformation it will be 6,553,500 defensive deferrals and 10 real waits.
These defensive deferrals aren't so expensive in terms of CPU time, but they ARE very expensive in terms of wall clock time. All other work must be halted so the event loop code can run. Eventually synthetic deferrals dominate the wall clock cost of running the program. This isn't hypothetical either. Here's someone trying to build steam parsing on Node and finding that it's too slow to be useful: https://github.com/nodejs/node/issues/31979
I think HTMX has a wall where it makes sense to pivot to something else. In your case I’d imagine using something like Svelte would get you the same speed benefit over React but without the extra work required to get the agent to cooperate.
Solid work, but it would be really cool if we can also test Pokemon motions and how the game responds in real-time. Is an agent able to think about reactions, directional movements and attack patterns of each Pokemon is where the real intelligence test lies.
Traditional languages may have their limitations, but [C++, Rust, JavaScript, TypeScript etc] can still do pretty well.
The point of using a framework is to reduce mental load at expense of customizability. The moment you need to change something in the framework - this mental model falls apart.
Obvious solutions are to vendor your dependencies (compile the framework from owned source) or to drop to the lower level of abstraction.
LLMs should have no problem using browser/node APIs directly since they're very well used, well documented, and not changing as much as higher level software does.
my experience is that one-shotting a simple front end works great. Then you want to add features and move things around and each turn starts getting slower and the single page with JS and CSS and HTML starts to turn into a 3000 line monster and your context window starts to creak under the strain of even simple changes, because the LLM has to keep more and more of the application in its head just to make relatively small changes without breaking something else. Either you should have started with some kind of framework with hygienic rules on how to separate concerns or at minimum a good set of coding standards that force the LLM to start building clean components from scratch. The benefit isn't necessarily cleaner code for its own sake, it's that the LLM can work on one part of the application without having to understand the whole thing every time. That being said, once you have a 3000 line prototype it's not that complex to simply ask the LLM to refactor it into a set of orthogonal components. As long as it was building unit tests using playwright or something this can turn your slop into framework code cleanly. The interesting question is whether you saved anything by putting off that structure in the first place.
I run into this problem turning claude artifacts into things I might want to maintain longer term.
And a little research turns out that anthropic itself makes available a *react* based artifact builder so you don't end up with SLOP from the get go. You could probably modify the template to work with your framework of choice.
Besides a rewrite to another framework using AI, another option is to modernize the framework with AI instead. Personally, I started to like Mithril after having worked with it for a few years. Instead of rewriting it to a better maintained alternative (mithril doesn't have much active development going on since 2015), I used agents to add signals, proper state management, typing, ssr, computed properties, Bun tooling and more to it. Thanks to the existing test suite, changes landed quite reliably. Source: https://code.garage44.eu/jeroen/mithril
Yeah it's really enjoyable to be able to take old, stale dependencies, and simply make them into something great, typesafe, ESM, well tested etc, without having to change the whole codebase.
There are also new minimalist frontend spa frameworks built from the ground up to be clean and simple and fast and easy for ai. E.g. https://arrow-js.com/
That truly looks agentic. Few commits in spring 2021 then nothing until a flurry of commits in spring of 2023, then absolutely nothing until March 2026, then we get 160 commits, and fast-forward until today, not a single change since then. https://github.com/standardagents/arrow-js/graphs/contributo...
Maybe it's just me, but if I were to start depending on other's UI frameworks again, then stability would be the first thing I'd look for, and with that I'd probably want to stay as far away from anything "agent" as I can.
Edit: I just realized that that "framework" is the same ArrowJS that used to be a "library" and the selling point was how small it was, and how it wasn't a framework (https://web.archive.org/web/20230609020338/https://www.arrow...), incredibly funny they pivoted into making it a fully fledged framework after all.
It's astonishing to me that even after a decade of SPA frameworks, most authors don't understand how a browser engine like Chrome works. There's enormous cost of manipulating the DOM from JS, as HTML elements get bound to JS objects lazily.
An actual high performance framework should manipulate HTML as a string directly, or through HTML templates (another feature that has existed in most browsers for a decade).
If you're not building a complex application on top of the web stack (interestingly these increasingly use WASM and their own GUI frameworks, so another moot point), but building an interactive consumption website (scrollable lists of static contents), I'd say instead of fronted frameworks, what most people actually would need is Chrome's experimental declarative partial updates:
One size never fits all on the web. Although those references to elements can be costly they’re also valuable. If all you used was HTML string manipulation then event handling would be an utter nightmare. You’d have to make every event handler a global variable so you can specify it in onchange=“” callbacks and the like.
I’m the first to complain about the bloat of modern frameworks but stepping all the way back to HTML strings would be a total mess for anything relying on heavy interactivity.
this doesn't even benchmark anything really wrt user experience, so what does that have to do with the article?
the author measured near perfect scores on lighthouse across the board, which, i mean no surprise there?
then it has takes about payloads and ttfb, which is nearly meaningless without implementation details and one being an expert in each framework, imo.
are you just ranting about javascript in browsers because its accepted and articles like this become a place to welcome such without anyone caring about the topic?
I don't understand how does manipulating html as string exactly makes anything better? wouldn't that cause for the whole page to just re-render with every small change?
There are server side frameworks that use web sockets so you can refresh small parts of a page and not the entire page. This involves smaller round trips from client browser to web server. In my opinion, for data intensive applications it makes more sense rather than REST APIs returning JSON payloads, parsing JSON into objects client side, and then update the DOM.
I think a lot of JS developers fail to recognize the variations of client systems power or people's usage patterns like how many tabs are open, how much GB of memory is their browser using, is the client machine paging out to disk, stuff like that. Not everyone is running a MacBook Pro so heavy client side JS apps tend to be "slow" to end users, at least perception.
String manipulation for HTML is a great way to introduce security vulnerabilities.
WASM is a non-starter for most web applications due to initial binary download.
Advising to use some experimental feature in one browser does not seem like a great idea.
JavaScript frameworks are not perfect but they exist for good reasons. People that brush them away usually lack the experience and understanding on the topic.
I don't disagree or really have a dog in the fight for three out of your four points, but it's unfortunate that WASM gets such a bad rap. The blobs are large because popular compilers force the semantics of popular languages into the Turing tar pit. WASM binaries are pretty compact by design:
> There's enormous cost of manipulating the DOM from JS, as HTML elements get bound to JS objects lazily.
And yet, 95% of these "framework comparisons" and "anti-framework evangelists" build their opinions on examples that do little (if any!) dom manipulation after the initial rendering. Which is just not the reality of commercial products.
these are frameworks on frameworks though. nuxt vs angular or next vs htmx isn't really the same thing.
also, "the app is very simple" kind of makes the results meaningless. what is the point in using a framework for a simple application if you care about these sort of metrics?
try benching a application with tens of thousands of modules.
113 comments
[ 4.1 ms ] story [ 24.1 ms ] threadVery easy to setup and way more readable than the equivalent React code.
Django?
If you aim to make small apps that don’t represent complex real-world applications you should not use Angular.
But blanket statements like yours are what I hate the most in software industry.
Not necessarily that Angular would win that, but I imagine that it would at least significantly shuffle the order.
and what % of users have JS turned off? 0.00001%?
The only feature that appears to require JavaScript is the ability to search.
The only feature that appears to require JavaScript is search.
I have noped out of so many sites that are - or should only be - serving simple content when I see the "please enable JavaScript" notice or site just plain breaks. It's so disappointing and irritating.
In this regard alone, it will make a lot of sense to spend extra $2 and 2 mins to trade off for a long-term maintainable codebase and code you can reason about than just something made quickly just to get it deployed fast.
In my personal use case, that would be Svelte 5 for me and I'm sure it will be something else for everyone.
Server side page generation with a sprinkle of js will give you the same results with GBS less of packages and comple time
Plus all the other vanilla advantages: fewer dependencies, lower maintenance, less retraining, etc…
Now that you don't write the code now, I don't see why I would pick React style libraries unless the codebase is already there.
It's all about how much interactivity you need. A lot of business web apps are full featured commercial software packed in SPA form. You will need a lot of stuff client side and without framework it will be a mess. Unless you write framework yourself but the you are reinventing a wheel.
I think unless you have a very low number of features I don't see it working.
In my 3 previous companies I had similar issues so I think it's widespread.
All of these thing still matter no matter what you are coding with.
I hope I'll be the last person on Earth writing code by hand.
The overwhelming majority AI spend is being done by startups funded by venture capital.
Meanwhile, big companies have massively cut/capped AI spending at the exact time these companies need to triple prices to get any margins at all.
Perhaps dead internet theory applies more than normal to programming forums.
> My goal here is not to write the end-all-be-all benchmark for “I’m a vibe-coder, which framework should I choose?” The point of this post is to demonstrate that it’s possible in the era of AI coding to still make decisions based on evidence rather than vibes.
But it’s obvious that the article will be understood as a useful benchmark, so author probably should have addressed that point earlier and more thoroughly.
Taking the authors pov for a moment, they just showed you how to put all your criticisms to work in making a newer better benchmark :)
I have most of my apps in it without much trouble.
One of my recent ones had a very complicated form and state management.
AI really struggled with HTMX in that use case.
Like the form might work but the page would take 30s to load. Or some state would randomly drop or a toggle wouldn't work after changing a dependency.
If I rewrote that in react it would have one shot it without a doubt. Some things are just better models for different problems.
For the record I eventually got enough tests in place to keep the agent honest and the HTMX version is now a lot faster anything I could have got out of react but yeah, it was an adventure.
Async JavaScript using callbacks had a learning curve, but once you learned how to contain it and treat callback indentation as an opportunity to refactor it felt similar to coding in lisp.
The problem was the learning curve, and the fact you had to rewire your brain a bit compared to coding in something procedural.
As much as possible should be happening locally, synchronously on the computer, in-process, or at least without yielding your thread context (and even then there are things like page faults which async/await wont save you from, they are 'invisible' to a regular developer).
While you might dismiss this idea, page faults used to be THE leading cause of delays back when hard drives were the norm.
This hurts most badly for iterators.
Files are usually read from disks in chunks of 64K bytes. If you present the data as an async byte iterator you'll get 65,534 defensive deferrals, and one actual wait.
Of you have ten layers of transformation it will be 6,553,500 defensive deferrals and 10 real waits.
These defensive deferrals aren't so expensive in terms of CPU time, but they ARE very expensive in terms of wall clock time. All other work must be halted so the event loop code can run. Eventually synthetic deferrals dominate the wall clock cost of running the program. This isn't hypothetical either. Here's someone trying to build steam parsing on Node and finding that it's too slow to be useful: https://github.com/nodejs/node/issues/31979
The solution is stream iterators. They are sync when they can be and async when they must be: https://docs.bablr.org/architecture/spacetime
I'm still sour why goto doesn't exist in javascript
Traditional languages may have their limitations, but [C++, Rust, JavaScript, TypeScript etc] can still do pretty well.
Obvious solutions are to vendor your dependencies (compile the framework from owned source) or to drop to the lower level of abstraction.
LLMs should have no problem using browser/node APIs directly since they're very well used, well documented, and not changing as much as higher level software does.
I run into this problem turning claude artifacts into things I might want to maintain longer term.
https://github.com/anthropics/skills/blob/main/skills/web-ar...
Maybe it's just me, but if I were to start depending on other's UI frameworks again, then stability would be the first thing I'd look for, and with that I'd probably want to stay as far away from anything "agent" as I can.
Edit: I just realized that that "framework" is the same ArrowJS that used to be a "library" and the selling point was how small it was, and how it wasn't a framework (https://web.archive.org/web/20230609020338/https://www.arrow...), incredibly funny they pivoted into making it a fully fledged framework after all.
An actual high performance framework should manipulate HTML as a string directly, or through HTML templates (another feature that has existed in most browsers for a decade).
If you're not building a complex application on top of the web stack (interestingly these increasingly use WASM and their own GUI frameworks, so another moot point), but building an interactive consumption website (scrollable lists of static contents), I'd say instead of fronted frameworks, what most people actually would need is Chrome's experimental declarative partial updates:
https://developer.chrome.com/docs/web-platform/declarative-p...
Which basically stream HTML fragments from the web.
I’m the first to complain about the bloat of modern frameworks but stepping all the way back to HTML strings would be a total mess for anything relying on heavy interactivity.
the author measured near perfect scores on lighthouse across the board, which, i mean no surprise there?
then it has takes about payloads and ttfb, which is nearly meaningless without implementation details and one being an expert in each framework, imo.
are you just ranting about javascript in browsers because its accepted and articles like this become a place to welcome such without anyone caring about the topic?
I think a lot of JS developers fail to recognize the variations of client systems power or people's usage patterns like how many tabs are open, how much GB of memory is their browser using, is the client machine paging out to disk, stuff like that. Not everyone is running a MacBook Pro so heavy client side JS apps tend to be "slow" to end users, at least perception.
WASM is a non-starter for most web applications due to initial binary download.
Advising to use some experimental feature in one browser does not seem like a great idea.
JavaScript frameworks are not perfect but they exist for good reasons. People that brush them away usually lack the experience and understanding on the topic.
And yet, 95% of these "framework comparisons" and "anti-framework evangelists" build their opinions on examples that do little (if any!) dom manipulation after the initial rendering. Which is just not the reality of commercial products.
also, "the app is very simple" kind of makes the results meaningless. what is the point in using a framework for a simple application if you care about these sort of metrics?
try benching a application with tens of thousands of modules.