HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
krausest
js-framework-benchmark
JavaScript2016–2026
krausest / js-framework-benchmark

js-framework-benchmark

A comparison of the performance of a few popular javascript frameworks

38Distinct people
47Mentions
1Explicit recommenders
7.5KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A comparison of the performance of a few popular javascript frameworks

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

Very cool. I love the zero dependencies. So the funding comes from selling the data grid, etc? BTW you should add Lemonade to the JS benchmarks:…

pier25 used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:03:16 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year47 dated mentions

Observed mentions: 2016-07-10 04:17:19 UTC to 2026-06-09 16:07:10 UTC.

02462016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 5 mentions; 2 submissions, 3 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 7 mentions; 1 submissions, 6 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 4 mentions; 3 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC615
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC505
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC505
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC523
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC716
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC404
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC431
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC413
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC404
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC211

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
js-framework-benchmark This is a simple benchmark for several javascript frameworks. The benchmarks creates a large table with randomized entries and measures the time for various operations including rendering duration. Security advice Currently there are 186 implementations in this repository. It's of course impossible for me to make a security assessment for all those implementations. npm ci and npm install can execute arbitraty commands, so they should be executed only for packages you trust. Consequently I build on a dedicated virtual private linux server such that I don't have to install the packages for all those implemenations on my laptop. There's a prebuild build.zip for each chrome release you can download such that you can avoid installing the packages from all implementations. (I don't know of any (attempted) case for malicious packages in this repository, so please take it just as a general warning.) The server implementation in this repository should only be started on your local machine and access should be restricted to your local machine. I recommend against starting the server such that it can be publically accessed from the internet. About the benchmarks The following operations are benchmarked for each framework: create rows: Duration for creating 1,000 rows after the page loaded (no warmup). replace all rows: Duration for replacing all 1,000 rows of the table (with 5 warmup iterations). partial update: Time to update the text of every 10th row for a table with 10,000 rows (with 5 warmup iterations). select row: Duration to highlight a row in response to a click on the row. (with 5 warmup iterations). swap rows: Time to swap 2 rows on a table with 1,000 rows. (with 5 warmup iterations). remove row: Duration to remove a row for a table with 1,000 rows. (with 5 warmup iterations). create many rows: Duration to create 10,000 rows (no warmup) append rows to large table: Duration for adding 1,000 rows on a table of 10,000 rows (no warmup). clear rows: Duration to clear the table filled with 10,000 rows. (no warmup) ready memory: Memory usage after page load. run memory: Memory usage after adding 1,000 rows. update memory: Memory usage after clicking 5 times update for a table with 1,000 rows. replace memory: Memory usage after clicking 5 times create 1,000 rows. repeated clear memory: Memory usage after creating and clearing 1,000 rows for 5 times. update memory: Memory usage after clicking 5 times update for a table with 1,000 rows. startup time: Duration for loading and parsing the javascript code and rendering the page. consistently interactive: The lighthouse metric TimeToConsistentlyInteractive: A pessimistic TTI - when the CPU and network are both definitely very idle. (no more CPU tasks over 50ms) script bootup time: The lighthouse metric ScriptBootUpTtime: The total ms required to parse/compile/evaluate all the page's scripts main thread work cost: The lighthouse metric MainThreadWorkCost: Total amount of time spent doing work on the main thread includes style/layout/etc. total byte weight: The lighthouse metric TotalByteWeight: Network transfer cost (post-compression) of all the resources loaded into the page. For all benchmarks the duration is measured including rendering time. You can read some details on this article and in the wiki. Starting with chrome 118 the overall performance is computed as a weighted geometric mean. Official results Official results are posted on the official results page. To work on the results website, see website development and publishing. My blog has a few articles about the benchmark. Older results of this benchmark are outlined on my blog (round 1, round 2, round 3, round 4, round 5, round 6, round 7 and round 8). Snapshot of the results The current snapshot that may not have the same quality (i.e. results might be for mixed browser versions, number of runs per benchmark may vary) can be seen here Keyed vs non-keyed frameworks Some frameworks like React, Vue.js or Angular, allow you to create a 1:1 relationship between a data item and a DOM node by assigning a “key” attribute (or for Angular, specifying “trackBy” in *ngFor). If you use some identifier of the data as the key, you get the “keyed” mode. Any update to the data will update the associated DOM node. If you reorder the list, the DOM nodes will be reordered accordingly. The other mode is “non-keyed” and this is what e.g. vue.js uses by default for lists. In this mode, a change to the data items can modify DOM nodes that were associated with other data before. This can be more performant, since costly DOM operations can be avoided (e.g. first removing old nodes and then adding new nodes) and the existing DOM nodes are updated to display the new data. For React and Angular, using the item index as the key uses “non-keyed” mode for those frameworks. Depending on your requirements, the “non-keyed” mode can be a performance gain or can cause severe problems, so one must carefully choose the mode and check that the framework supports that mode. Read more here: https://www.stefankrause.net/wp/?p=342 1 Run pre-built binaries for all frameworks There are currently 186 implementations in this repository. Installing (and maintaining) those can be challenging, but here are simplified instructions how to get started. See the security advice above to read why that might be a good idea. 1.1 Prerequisites Have node.js (>=v20.9.0) installed. If you want to do yourself a favour use nvm for that. The benchmark has been tested with node v20.9.0. Please make sure that the following command work before trying to build: > npm npm -version 10.1.0 > node --version v20.9.0 1.2 Downloading the pre-built binaries and starting the server building all frameworks can be challenging. There's a new way that allows to skip that and just run the benchmark without building all implementations. Start with checking out a tagged release like that. Pick the release that you want (e.g. chrome 100): git clon
Read the full README on GitHub

What Hacker News says

47 sources
rheohile10·Jun 9, 2026Submission

Show HN: Plastron – A spreadsheet you grow into an app, in one index.html

Plastron is a spreadsheet starting with one cel (元) whose formula generates the a readme DOM element but you can make sheets of cels with formulas like =cels(8, 5). It's a single index.html — no build, no server, no install — so it runs locally, offline, and free. Excel is maybe the most useful software ever written, but the moment a sheet wants to be a real app — a UI, a file, a database, something to share — you fall off a cliff and rewrite it as "a real application" (framework + backend + deploy), usually after pleading with IT over licenses. Meanwhile every browser already runs JS, WASM, SQLite, and a filesystem API. An index.html should be all you need. Things to try on the page: =cels("anim", 2, 1, at("a1", "=def(\"ball\", \"js\", \"i => [30+280Math.abs((i/20)%2-1), 30+200Math.abs((i/14)%2-1)]\")"), at("a2", "=simulate(\"ball\", 120
Read the rest
)")) =cels("data", 2, 1, at("a1", "=db(\"app\")"), at("a2", "=sql(\"app\", \"create table t(a,b); insert into t values (1,2),(3,4); select * from t\")")) Imagine somebody dm'ing you a formula for some bs b2b saas app It's early and meant to be built on. I'm sure there are bugs. No version control yet, no .xlsx import/export, and the traditional Excel formula set isn't there. Code (MIT): https://github.com/rheophile10/plastron also you can still play free doom at this vestigial stub https://plastron.ca/os/ I benched plastron against krausests library https://news.ycombinator.com/item?id=45259345 and you can see the first pass version of plastron there https://github.com/krausest/js-framework-benchmark/pull/2015 This afternoon I PR'd the more recent plastron. It has some modest improvements https://github.com/krausest/js-framework-benchmark/pull/2029 Thanks @1v100000 @mynamebedan @lionkimbro for ill-advised encouragement Thanks to @Ki_fun_thoughts for entertaining conversations about what thought bubbles of spiderman would look like in a more perfect world Thanks to Claude and Grok who laboured with this prompt: "make me spreadsheet... masterpiece" Thank you for reading this. Now give me cruel and harsh criticism in the comments. Or steal this app and do what I was trying to do better than I could. https://www.instagram.com/reel/DRFytotD2hV/?hl=en @Ki_fun_thoughts wiki: https://www.tinygnomes.com/qwiki.cgi?mode=previewSynd&uuid=W...
2 points · Open discussion
Plastron is a spreadsheet starting with one cel (元) whose formula generates the a readme DOM element but you can make sheets of cels with formulas like =cels(8, 5). It's a single index.html — no build, no server, no install — so it runs locally, offline, and free. Excel is maybe the most useful software ever written, but the moment a sheet wants to be a real app — a UI, a file, a database, something to share — you fall off a cliff and rewrite it as "a real application" (framework + backend + deploy), usually after pleading with IT over licenses. Meanwhile every browser already runs JS, WASM, SQLite, and a filesystem API. An index.html should be all you need. Things to try on the page: =cels("anim", 2, 1, at("a1", "=def(\"ball\", \"js\", \"i => [30+280Math.abs((i/20)%2-1), 30+200Math.abs((i/14)%2-1)]\")"), at("a2", "=simulate(\"ball\", 120
Read the rest
)")) =cels("data", 2, 1, at("a1", "=db(\"app\")"), at("a2", "=sql(\"app\", \"create table t(a,b); insert into t values (1,2),(3,4); select * from t\")")) Imagine somebody dm'ing you a formula for some bs b2b saas app It's early and meant to be built on. I'm sure there are bugs. No version control yet, no .xlsx import/export, and the traditional Excel formula set isn't there. Code (MIT): https://github.com/rheophile10/plastron also you can still play free doom at this vestigial stub https://plastron.ca/os/ I benched plastron against krausests library https://news.ycombinator.com/item?id=45259345 and you can see the first pass version of plastron there https://github.com/krausest/js-framework-benchmark/pull/2015 This afternoon I PR'd the more recent plastron. It has some modest improvements https://github.com/krausest/js-framework-benchmark/pull/2029 Thanks @1v100000 @mynamebedan @lionkimbro for ill-advised encouragement Thanks to @Ki_fun_thoughts for entertaining conversations about what thought bubbles of spiderman would look like in a more perfect world Thanks to Claude and Grok who laboured with this prompt: "make me spreadsheet... masterpiece" Thank you for reading this. Now give me cruel and harsh criticism in the comments. Or steal this app and do what I was trying to do better than I could. https://www.instagram.com/reel/DRFytotD2hV/?hl=en
In Plastron: A spreadsheet you grow into an app, in one index.html
I had similar concerns when I made the jump from a custom data class (with methods like `set`, `get`, `increment`, `push`, etc) to a transparent `Proxy` around native JavaScript objects. I did some quick benchmarks back then, and concluded that it was actually not meaningfully slower. Modern JavaScript engines are awesome! :-) Aberdeen is not in js-framework-benchmark yet, but I've done a pull request https://github.com/krausest/js-framework-benchmark/pull/1877 -- By my own testing, performance is similar to something like react (while of course destroying React on time-to-first-paint, bytes transferred, etc). However, this test is not a particular good fit for Aberdeen, as lists in Aberdeen are always sorted by a given key (it maintains an ordered skiplist for the data). The test only requires the easy case: sort by creation time. So Abe
Read the rest
rdeen is doing some extra work here. With regard to reactive data transforms: Aberdeen provides some (reactively 'streaming') helper functions for that (`map`, `multiMap`, `partition`, `count`). But these are mostly based on the `onEach` primitive, for reactive iteration. Take a look at the `map` implementation, for instance: https://github.com/vanviegen/aberdeen/blob/a390ce952686da875... Is past projects, we've been using things like this a lot. Pretty easy and fast!
In Show HN: Aberdeen – An elegant approach to reactive UIs
great points! i do a lot of JS benchmarking + optimization and whole-program measurement is key. sometimes fixing one hotspot changes the whole profile, not just shifts the bottleneck to the next biggest thing in the original profile. GC behaves differently in different JS vms. sometimes if you benchmark something like CSV parsers which can stress the GC, Benchmark.js does a poor job by not letting the GC collect properly between cycles. there's a lengthy discussion about why i use a custom benchmark runner for this purpose [1]. i can recommend js-framework-benchmark [2] as a good example of one that is done well, also WebKit's speedometer [3]. [1] https://github.com/leeoniya/uDSV/issues/2 [2] https://github.com/krausest/js-framework-benchmark [3] https://github.com/WebKit/Speedometer
In JavaScript Benchmarking Is a Mess
Sorry, this is a bit out of my area of expertise (especially in non-React frameworks), but until someone more knowledgeable comes along, maybe I can at least offer some links for getting started? A writeup: https://blog.logrocket.com/rendering-large-datasets-vue-js/ As for implementation, this is probably a situation where I'd reach for Someone Else's Library™ instead, at least to learn from. Maybe something like https://www.ag-grid.com/example/ (try the 100k row example) with maybe a serverside data model: https://www.ag-grid.com/vue-data-grid/server-side-model-upda... That's a ready-made open-core implementation (paid additional features), but you can see an example of how to make an performant implementation. Often, big tables like that can use some sort of virtualization (https://www.ag-grid.com/vue-data-grid/dom-virtualisation/), or
Read the rest
here's another lib that does something similar: https://tanstack.com/virtual/latest There is also a JS framework benchmark at https://github.com/krausest/js-framework-benchmark and a vue-pinia implementation at https://github.com/krausest/js-framework-benchmark/tree/mast... Lastly, I would say it might be worth considering how the whole dataset works, holistically, as in whether the client really needs to handle all that data at once or if it can be streamed in chunks to & from the server, maybe with a bit of buffer in every direction. It's the same windowing concept, just moved to the network. And of the data on the client, how much of it is bottlenecked by rendering vs other in-memory operations (sorting, filtering, pagination, etc.) -- can you speed that part up with any better algorithms or data structures? But it sounds like your main bottleneck right now is rendering large datasets into the DOM, so hopefully some of those above will help. At some scale, it might also be worth considering moving out of the DOM altogether and into a canvas, like https://canvas-datagrid.js.org/ or https://github.com/xwinstone/canvastable?tab=readme-ov-file. The DOM isn't really made for something like that, and it's pretty amazing what the libs can do, but the canvas can be much much faster. You do lose all the built-in DOM functionality though so you end up having to recreate a lot of functionality (like search, selection, drag & drop, etc.) ------ Good luck! I hope someone comes along with more experience and wisdom to share.
In Ask HN: Fastest Async Front-End?
Strange then that frameworks advertise how fast they are at rendering, mutating, and creating objects in the DOM, and one of the main JS benchmarks everyone likes to measure their performance by is literally a benchmark about DOM manipulation: https://github.com/krausest/js-framework-benchmark Oh wait. It's not strange. Because state manipulation is a largely solved problem, and even the least performant state manipulation is blazingly fast. However, presenting components in the browser's DOM is tens of magnitudes of orders less performant than anything you can throw at state manipulation. And every single framework is busy solving one single problem: how do we touch the DOM as little as possible?
In Web browser as GUI, with your preferred language in the backend
That's an interesting comparison because: - Svelte is actually strangely slow, I mean there's *one* interesting optimization that having a custom compiler/transform allows you do to for free, which is deep cloning nodes in one go rather than creating them one by one each time, and they ain't doing it. Also, I don't have proof of this anymore, but I had tried running my relatively naive framework without the deep cloning trick, and without any custom transform or compiler at all, on that benchmark, and it was _still_ significantly faster than Svelte. Like Svelte is not that fast when you look at it closely, despite what the perception of the average developer might be, or what the marketing might say. - Inferno is fast for real in that benchmark, and it isn't using signals, which is very interesting. I don't know how Inferno works in depth
Read the rest
, but looking at the Inferno implementation for that benchmark [0] I see some shenanigans. Like what's that "$HasTextChildren" attribute? Why is my event handler created like that? Like I'm doubtful that the result in the benchmark will actually translate exactly to the real world. - It's interesting also: if the VDOM is pure overhead why is Svelte creating an object for each instance of a component, kinda like React is doing? You don't strictly need to do that, as proof of that Solid doesn't do that (in production builds), because that's pure overhead for real there. [0]: https://github.com/krausest/js-framework-benchmark/blob/6388...
In Virtual DOM is pure overhead (2018)

Showing the 15 most recent of 47 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.