As of right now (9:52 AM ET on March 26, 2016) there are 259,191 packages on NPM. Yes, that’s more than a quarter million packages.
Imagine a library with no books, instead being filled to the gills with fortune cookie fortunes. That are tied with strings to each other.
Now, what is the point of all this? Will it make it easier to write apps? Will it make them work better?
Growth for the sake of growth is the ideology of the cancer cell.—Edward Abbey
I don’t think short and to the point libraries are evil. I actually launched Micro.js a few years back to highlight useful, small libraries. However, I do not think the proliferation of essentially trivial code snippets that are packaged up is a good thing.
Guess what? In the real world, this model quickly leads to a multitude of issues. The most obvious example is that if a package is removed for any reason, chaos quickly spreads.
That’s actually not the main problem though. As a developer of software, your job is it to find the simplest solution to a problem. “Simplest” is a bit vague, so let’s define it as “does functionally work, is performant (enough), is relatively easy to understand and is not taking too long to implement”.
“There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.”—C.A.R. Hoare
So let’s break this down:
“Is performant” is the first hurdle. While the code itself probably is fine (though you won’t know until you measure it yourself), it has to be pulled in from a central repository, and it has to be kept up-to-date, which adds extra time during development and later issues when deploying (imagine the repository is temporarily down, the package is no longer available, something broke in a minor or patch release, etc.). You’ll need a build system, and you need one that offers workarounds for these problems (like local caches). In essence, this is adds complexity. And complexity is the enemy of productivity.
“Is relatively easy to understand” is where it gets hairy. Every library and module you add to your code basically creates a black box where input goes in and output comes out and in-between there’s magic. Magic that you have to go in and understand to see if the modules actually behave like you think they do. This package for example, provides a method that cuts off a string at a given maximum length and adds an ellipsis. Now, to find the package, add it to your build system, review the code if it actually does what you want—is it worth using a module? For something you can implement in one line of code?
“Not taking too long to implement”—how long would it take you to write a function that cuts off a string or checks if a number is positive or adds left padding? Many functions you’ll find in a standard library are likely trivial in nature, but having an agreed-upon standard API to do things will speed up implementing code (fewer instances of “is there a library for this or should I code it myself”). Bonus: other people reading your code can concentrate on learning about dependencies that actually matter instead of the 5th implementation of “leftpad”.
“Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves.”—Alan Kay
There’s a great metaphor in the German language, which is “Eierlegende Wollmilchsau” or “Egg-laying-wool-milk-pig”. It means a thing that tries to be everything. And ultimately the never-ending complexity causes it to fail.
I appreciate that some improvements are underway (like the aforementioned additional APIs for some built-in objects), but I’d love to see a concerted effort to cast aside new language features for a while and really get to work on an underlying standard library.
What if we developers would make things simpler instead of more complex?