E.g. imagine C++'s Boost libraries: That's I think ~150 libraries with dependencies among each other? Now imagine there was no need to publish them together, so each of them is an individual library that could pick any random dependency, not just primarily from inside the set of 150. And split some of them up in 4-10 pieces doing parts of their task. And external projects of course also then depend only one some subset of those parts.
A relative lack of a standard library maybe seeded the principle that people go looking for libraries for small things.
But in the end JavaScript needs a much better standard library.
There are obviously upsides to having a large standard library, but there are also significant downsides: because of Javascript's position on the web, it is very hard to remove things from the language when we get them wrong, and because Javascript is so widely used, it is very difficult to know in advance which implementations and styles of coding should be preferred.
So for example, I'm happy that we have native Promises now, but I'm also happy that we waited until basically the entirety of external library authors had settled on an interface, and I'm even happier that we decided that deferreds were unnecessary since they could be easily recreated with normal promises.
Of course there are downsides to preferring external libraries instead of native ones, but in Javascript this is a calculated choice. And I agree that JS culture encourages developers to take this too far. Even with a tiny standard library you probably don't need a leftpad package.
It's just that those downsides look a lot worse, because in the JS community we lack good security practices about freezing packages. We also assume that NPM is secure by default, instead of a fancy wrapper around Github. We don't have a way to make sites immutable. And we have really stinking awful sandboxing in NodeJS, and (arguably) insufficient sandboxing in the browser.
I typically get a little bit of pushback on this, but I advise people who are building end-user applications or a website as opposed to a library to commit their dependencies to Git. I also advise enterprise developers to avoid using packages that haven't been audited unless they're willing to read through the source code themselves -- and if you find an audited package, download that version and check the hash. That one in particular is a hard sell, I've heard developers tell me that it's literally impossible for companies to audit their Javascript libraries. I find that mindset really, well, disappointing -- especially since those same companies seem to have no problem blaming NPM for not auditing everyone's libraries.
On the browser side, I advise people to self-host packages instead of using commercial CDNs, or at least to use subresource integrity policies[0]. That doesn't protect you from a compromised server, but it does protect you from a good number of XSS attacks.
This is annoying of course. In an environment like Linux, on the server you'd use CentOS and you'd have strong guarantees about stability because you wouldn't be installing random packages from Github. On Linux you also get better checksums around your packages. Linux sandboxing isn't very good, but it's not like Node's is any better. I think on the web, we're really behind on this stuff.
But I don't think expanding the standard library helps with any of that. I think it's a band-aid fix.
[0]: https://developer.mozilla.org/en-US/docs/Web/Security/Subres...
Maybe standard libraries need to get bigger for JS.
Also since the code has to be downloaded (or uploaded to small lambdas, for example), JS developers are generally weary of depending on large libraries.
Isn't a dependency tree of thousands of small, interdependent libraries essentially just a large, distributed library?
Is there really a benefit to that versus compiling those dependencies to a single file, especially given how many NPM packages are just a single small function? The end result in many cases would probably be smaller than a lot of old JQuery plugins.
Yes and it's a thousand times worse than a single, large library.
While I do think making things easier for developers is a good goal, making the wrong things too easy (that is, making libraries that become very heavily depended on) results in the problems of Node.js (and I would argue the same is true for Rust). Maybe I'm just a curmudgeon, but I really have a sour taste in my mouth when I look at how Node.js and Rust do library management -- it's making it too easy to make a small library which doesn't really work and then people depend on it.
I once tried to write a simple IMAP cloning utility in Rust and found 4 IMAP crates -- none of them worked properly and all of them incorrectly handled several core parts of the IMAPv4 spec. I figured out later that they all appeared to be forks of one another (or they copied each others' APIs), but that doesn't help matters -- why are forked crates taking up more space in the global crate namespace? The "imap" crate doesn't implement IMAP properly!
Python had this problem (in a lesser degree) too with pip, but I think having a larger standard library and lots of time to mature allowed them to overcome it.
I noticed this problem with Perl and CPAN: there were dozens (well, several) email-sending packages, none of which were near complete. (Speaking SMTP is easy, an actual MTA is hard.)
I suspect there are similar issues in Java-land, although I haven't used Maven-derivatives enough to find out.
It's the wave of the future: make it really easy to share and use libraries, and get a crap-ton of low-quality libraries.
Another factor that probably helps is that most operating systems are built off C derivatives and thus usually are already carrying common libararies as dlls
How so?
It's a failing of the Unix model with a small silver lining in that C projects tend to go out of their way not to have to make the build any harder than it already is.
>> I think the answer is everything in your standard library plus some of the stuff you would use 3rd party dependencies for in your own project.
> Even in C with its tiny standard library you don’t see this kind of explosion.
I think one of the largest factors is that client-side JS doesn't have a good solution to the problem of dead code elimination.
There are solutions like Google Closure (the JS-to-JS complier), but it's difficult to set up and not many people use it. Instead, it seems like people have moved to lots of small dependencies so they can essentially do dead code elimination by hand.
Because there's almost no friction to add a new dependency, it's often easier to add one simple thing than roll your own.
Note that nobody uses 1700 dependencies directly. Your project might use 5 deps for the 5 things it needs, but each of these libraries will use a few libraries for smaller pieces of functionality their library is composed of, and so on.
It also has 1103 total dependencies.
The problem is that something this basic is considered a complete library. If you know regex you could write this on your coffee break. If you don't, you could look it up and still write in on your coffee break. If you want trim and do anything else with a string, you need another dependency tree.
This is not even really a problem with javascript lacking a standard library, so much as a problem with the accepted practices of the javascript community.
When the trim library was needed, you likely also needed to support IE8.
But IE8 has a bug where \s doesn't match a non-breaking whitespace \u00a0 - http://www.nivas.hr/blog/2012/01/19/non-breaking-white-space...
And you need to decide whether you polyfill or ponyfill the function.
Yes you can theoretically do a trivial function in your break. With real browsers in practice you will often find your trivial function just isn't trivial.
But the string trim package mentioned above is that trivial.