I'm sorry if anything I wrote came across as condescending; that was not the intent. You seem reasonable enough, and objectively I agree with much of what you've said. However, I think we've been talking slightly at cross-purposes.

I won't try to go point by point now as these comments have become very long, but overall the difference between our positions (as I intend mine and as I currently understand yours) seems to be that you're focussing on specific technologies like JavaScript or React, while I'm talking more holistically about the entire ecosystem around them.

For example, you have talked about backward compatibility being excellent within JS-the-language, and about React continuing to support its class-based API alongside the functions-and-hooks alternative. That compatibility is not in dispute.

However, when I'm talking about stability, I'm also including everything that is built around JS or around React, the libraries and tools and documentation and people. And in these respects, the JS ecosystem is much faster moving and more fragile than almost any other language I have ever used.

The kind of bifurcation of APIs we've seen with React causes a lot of churn even if the library itself is still backward compatible. If you looked at blog posts or Stack Overflow answers or Reddit discussions about React from as little as three years ago, many of them would have little relevance to the newer API that has obviously become dominant within the community since then. On the other hand, if you hired someone with a couple of years of React experience today and asked them to maintain older code in your system that used the class-based API, they might have no idea what they were looking at. And if you found a useful library to work with React components but it only provides a hook-based API, again you can't use that functionality from your older class-based components. Your old code might still build, but it's essentially unmaintainable unless developers who have come to React more recently first learn what is effectively an entirely different library from their perspective, and even then you're limited in how much you can integrate that older code with more recent contributions to the ecosystem. (This paragraph is an elaboration on the point I was trying to make when I first joined this discussion.)

For the wider JS ecosystem, we've talked about the breaking changes in major tools like Babel and Webpack and in popular libraries like React Router. You suggest that these are "exceptional cases involving particularly poorly maintained libraries and tools". I suggest that there is, unfortunately, nothing exceptional about this sort of abandonment of earlier versions and interfaces within JS world. For one thing, Babel and Webpack aren't just any tools, they are arguably the two biggest names in the JS ecosystem, so when they break, the damage is widespread. For another, they are far from isolated cases. To give another example, Angular was React's big contemporary "competition" and it too essentially abandoned one API in favour of a radical rewrite for version 2, turning any project using the older framework into legacy code almost overnight.

Before React and Angular, we had a string of moderately popular UI libraries built around various levels of data binding. These were must-know technologies in their day for anyone who wanted to work on a project using them, but none remained popular for more than a few years, again leaving all of the individual knowledge and documentation and old code bases largely obsolete.

This pattern isn't unique to UI libraries, either. For example, as JS has evolved and added support for promises and then async/await, many older libraries whose interfaces weren't designed to support that programming style have been left behind, again including some that were very well-known and widely-used.

And with tools, it's a similar picture. Although Webpack is probably the most popular tool for building web app front ends today, over the years we've used shell scripts, self-contained tools like Browserify and Babel, task runners like Gulp and Grunt (with their own surrounding package ecosystems) to co-ordinate the ever-increasing number of tools used in build processes, more comprehensive tools like Webpack (again with a big surrounding package ecosystem) to try to unify everything in one place and bring some structure back, attempts to simplify the horrendous complexity that unification had introduced (the later versions of Webpack and the likes of Parcel), and now we're swinging back towards more specialised tools but in some cases with much better performance such as esbuild, but ironically these newer and better tools may be hard for a lot of projects to adopt because so many people are boxed in by their existing tools and have to wait for someone to provide some plug-in package for those existing tools in order to integrate the new ones. And again, breakage is not unique to Webpack. For example, not long ago, Parcel pushed out a breaking change, and because the effort from the Parcel devs is mostly focussed on the still-in-beta Parcel 2 that naturally has some major limitations of its own, this left teams using Parcel with broken builds either way until they figured out what the problem was and then probably rolled back to an earlier version of Parcel 1.

So I suppose my point is that all of that disruption can and does still happen frequently within the JS ecosystem, despite the backward compatibility of JS itself and the willingness of at least some of the big libraries to continue supporting old APIs after launching new ones. Stability, in the sense I'm using the term, implies a reasonable degree of backward and forward compatibility. The converse, unfortunately, does not hold. A good compatibility story is necessary but far from sufficient for a stable, productive ecosystem.