Off the top of my head, the best software I use seems to fall into two categories:
- Closed source software that requires buying a license to use
- Open source software that is specifically made for developers and promises to do one job well
Whatever falls in the middle of those two categories tends to suffer, in my experience.
If you think about it, web based software tend not to fit neatly into either category. Most of them are the following:
- Closed source but are either too cheap or are free
- Open source but promises to do way too many things, and also too cheap or free (describes a lot of frameworks and design tools)
Web technology and JavaScript became the dumpster slut of software ecosystems. The end users are not given a big enough reason to pay for them adequately or at all, product owners care little about quality and reliability because it's way too easy to get a zillion low quality users to look at ads, and the barrier of entry for new JavaScript programmers is so low that it's full of people who never think philosophically about how code should be written.
I think an additional problem with the JavaScript ecosystem specifically is external resources are extremely easy to access and their cost is usually borne by end user resources. Therefore they're too tempting for many developers to avoid. Unfortunately the runtime environment of the end user rarely matches that of the developers and seemingly "cheap" resource access at development/test time isn't cheap for the end user.
JavaScript is happy to pull in some library hosted on some third party service at runtime. For the developer/tester this ends up cached by the browser and/or at the edge of the CDN. A developer may also have topologically close CDN endpoints. This inspires them to pull willy nilly from third party libraries because to them they're cheap to access and they save time writing some utility function.
The same goes for CSS, APIs, or media resources. With JavaScript the delivery is a client issue and costs can be pushed entirely onto the client. If pulling in an external resource(s) costs a developer non-trivial money to store and serve they'll put more effort into tree shaking or other delivery optimizations. They may omit it entirely.
I think this massively contributes to the LEGO piece construction of a lot of web apps. It also contributes to performance robbing things like tag managers that insert a bunch of incongruent plug-ins only at runtime from an unbounded number of sources.
Don't agree that JS community is bad, it is the largest community of any language by far, and it has the most money invested into it by a huge margin. There is a lot of trash but there is some seriously good stuff, and you can find 10+ packages trying to do pretty much anything you can think of.
And yes, you can find 10+ packages to do pretty much anything... of which 8 are abandoned and no longer work on up-to-date Node versions or depend on other packages with known vulnerabilities.
Nobody else can understand how it's built, but for some reason that's not their problem? It's not like they're taking the time to understand how React is built, either. But as soon as you do something on your own, whoooa buddy. Cowboy programmer alert. It's not good engineering if it's a single, coherent, vertically integrated system. It's only good engineering if it's a mishmash of half-solutions teetering on top of each other.
I still do a lot of programming. And I expect my developers to be competent enough to read other people's code and figure out how it works, what it does, how to use it, based on the tests and plenty of extant examples.
I don't want developers who can only be productive in libraries that everyone else's is using/posting YouTube tutorials on/feeding LLM training corpus'.
The problem with adopting other people's software is that you have to make it work for your purposes, all while accepting it was only ever originally designed for their purposes. And if that's open source and you contribute to it, then you have to make sure all your changes don't break other people's work.
But with my own libraries, I can break anything I want. I have, like, 5 projects using them. It's not a big deal to discover an architectural problem and completely refactor it away to a newer, better design, propagating the change to all the others that use it in fairly short order.
And I don't have to argue with anyone about it. I can just do it and get the work done and prove it was the right thing to do long before any Github PR would ever get out of review.
I don't understand why people get so up in arms over npm modules, as if you could stand up code that does the same things in another language without having to manage dependencies.
Then people started stacking more and more things on top of those libraries, creating a giant dependency morass of microdependencies that larger frameworks are now build on top of. And because all these frameworks do things just different enough from each other, every larger library that a dev would want to integrate with those frameworks now needs a specialized version to work with those frameworks.
In most languages, if you want to know how something works, you can usually dig into your dependency tree and by the time you hit the stdlib's optimization spaghetti/language internals, you'll probably have figured out what's causing your snag/what the library is expecting out of you. In JavaScript, you hit the dependency morass and have to give up. Most competent devs then decide to pick another language.
You can write very legible JavaScript these days, even without a framework, but it looks nothing like JavaScript used in a framework.
The other language I know of with this issue is, ironically, Rust.
The one thing salvaging Rust for now is a lack of similar frameworks, but who knows how long that will last.
For example, in the 2000s and 2010s, javascript had the lowest barrier to entry by far thanks to browser dev tools, so a lot of what you saw was people with no prior experience teaching people with no prior experience. These people are still around, and while plenty have improved, they still form the basis of modern javascript practice.