April 12, 2018

Stop with the one function Javascript "libraries", please.

I get it: you need some CV-filler. The job market is competitive, and getting your name out there is important, but can you not do it by publishing 5 line npm modules, please? You’re actively harming the Javascript ecosystem.

Enter the Reddit discussion “When a modulus call is published as a NodeJS package with millions of downloads a day”, and the story of one particular character who has published a number of one-function NPM modules.

The developer in question - @jonschlinkert - has created a number of interlinked modules, mostly containing individual functions, which have now been adopted by major projects such as Webpack. The end result is that he’s cemented his own repositories and modules as a single point of failure that could threaten many mainstream packages and thousands of applications.

Libraries in the npm registry can disappear.

Everyone seems to be aware of the left-pad fiasco, where an individual developer opted to unpublish one of their libraries from the NPM registry. The result? Broken builds for thousands of other projects.

What spectacular functionaly did left-pad - relied upon by thousands - provide? Something a little like this:

export default (str, len, ch) => {
    const prepend = ch.repeat(len)
    const buffer = [prepend, str].join("");
    return buffer.slice(len * -1);

If you really wanted, you could write it in one line… and it would still appear readable.

export default (str, len, ch) => {
    return [ch.repeat(len), str].join("").slice(len * -1);

It’s simple enough that I’ve given you two implementations - completely off the top of my head - in one blog post. How many installations did this library have? Well, one current implementation has had over 865,000 installations.. in the past 7 days. This is despite the fact that native functionality is now available in the ECMAScript specification;

> "ello".padStart('12', 'H')
> "Hell".padEnd('12', 'o')

So why, after two years haven’t developers learnt from left-pad?

Nobody ever seems to audit their libraries.

This is arguably one of the most dangerous issues, and unfortunately I’ve yet to work in an environment where people have audited the libraries in use. Whilst I’ve seen companies actively audit the licensing from a compliance overview - primarily due to the threat of litigation - I’ve yet to see the same diligence applied to security concerns.

In my personal experience I’ve seen this mindset pervade companies in multiple industries - including those responsible for developing solutions for Healthcare clients. Surprisingly, I’ve even seen this issue in a company that specialise in.. erh.. analysing application dependencies for security issues.

Developers in general - but the Javascript/NodeJS community in particular - need reminding that each dependency that is introduced not only increases the attack surface, but is also effectively a black box of someone elses code. That’s not great.

It’s not even laziness… is it lack of skills?

Take the is-odd library, and the hilarious is-even implementation too, these are incredibly simple. So simple in fact, that one of the most common interview techniques to weed out non-developers - i.e fizzbuzz - uses a slightly more complex twist.

Consider that both libraries can be expressed in a total of 2 lines - or 4 if you want to package them up and expose them as a module. Here’s an implementation, and remember that this is the equivalent to two npm modules:

export default {
    'isOdd'  : (n) => (n % 2) == 1,
    'isEven' : (n) => (n % 2) == 0

These are both more trivial than the left-pad example above, and once you understand the modulo operator it is instinctive.. yet still these libraries exist. It can’t even be attributed to laziness though, as to utilise these libraries you need to (a) search google for the appropriate module, (b) install the appropriate module, and © import it to where you want to utilise it.

Which leads to the possible conclusion that many developers can no longer perform trivial tasks. That doesn’t quite make sense either though, because not only do these modules find themselves in some impressive applications, they also require knowledge of the language ecosystem and tooling.

If it’s so simple, then why are they used?

Essentially these libraries do become more complex, especially when you factor in things such as unit testing, safe guarding (i.e !(Number.isNaN(n) || isNaN(n)) and so on. There is a degree of additional safety as long as you check the code and ensure there is unit test coverage.

Ultimately though, it seems cynical that many of these - often similar - modules are packaged independently, often inflating the metrics that are recorded for the author on the npm registry. I have no qualms personally, nor do I think the ecosystem would suffer, from collections of utility functions. This is afterall what libraries like lodash are.

Whilst practice of releasing individual functions for standard tasks is actively harmful to the stability of the eco-system, there clearly is a distinct gap in the standard library - and perhaps it’s time that this was given more attention in subsequent ECMAScript specifications.

© Fergus In London 2019

Powered by Hugo & Kiss. Source available on Github.