Dating and Choosing New Software Packages: Red Flags to Watch Out For

Dating and Choosing New Software Packages: Red Flags to Watch Out For

Whether you're about to go on a date or you're evaluating whether or not to install a new software package, this article has you half-covered.

·

10 min read

When you start out building software projects, you will inevitably rely on some core libraries and packages. As your needs grow, you'll find yourself installing new packages from your tech's ecosystem to implement new functionality without needing to write it from scratch. This is great and allows us to be productive and build quality products. However, as time goes on, you'll realize that not every package makes for a great life partner and, just like in dating, sometimes you can afford to be picky.

Be warned. You are about to witness an exercise in metaphor stretching by an author with little dating experience - possibly because he spent too much of his spare time installing software packages.


Picture the scene. You're sitting at your desk in your home office. You can hear the rain against your window. The nutty caramelized scent of still-warm coffee is teasing your nostrils. But it's late. The cursor on your terminal window is flashing at you in time with the ticking of your watch. Maybe it's time to call it a night.

You pull out your phone, open up a dating app, and start swiping. Left, left, left, left. Pause. Left, left, left, left. Pause. "Oh, they look interesting!". Your thumb hovers over their profile picture. You look back up at your terminal window to see the command you were about to execute: npm install jquery. In your gut, you feel like you're about to make a mistake, but you can't put your finger on it.

You remember reading an insightful article by an intriguing author that somehow managed to cover both of these topics with surprising grace and eloquence. You find the article in your browser history and pull it up to read...


Stranger Danger

image.png

Alright, first things first: it's a scary world out there. Just like you wouldn't want to invite a total stranger around to your house on a first date, you don't want to be one of the first to install a relatively unknown package into your application.

The red flags for this are pretty clear:

  • A low number of installs on npm.
  • A low number of stars or contributors on GitHub.

"How bad could it be?", you might ask yourself. The answer? Pretty bad. Check out this issue in the event-stream repository from 2018, where a user unveils that the introduction of an unknown flatmap-stream package has suddenly exposed all consumers of event-stream to a malicious attack that attempts to steal cryptocurrency wallet information.

Funnily enough, this incident was brought about when the original maintainer of the repository handed over control to a willing volunteer. Another incident of "Stranger Danger".

While the issue was quickly corrected and the affected versions were removed from npm, not everyone will have gotten around to updating event-stream to the safe version. The flatmap-stream repository still lingers, with over 60,000 repositories depending on it as of writing.

image.png

Security isn't the only concern you should have when installing a relatively unknown package. Every additional external dependency adds a little bit of complexity to your overall application. Often, if I find a tiny library that I don't want to have to tie myself to, I'll copy and paste the parts I need (assuming the license allows it). This also has the advantage of being able to easily fork the implementation as your needs change.

You Don't Like Their Friends

image.png

In the last example, users of event-stream weren't just tying themselves to event-stream (a popular and well-developed package), they were also making a commitment to all of its dependencies. Clearly, some due diligence is needed that involves a background check on a package's dependencies.

But, just like social networks and family trees, the dependency chain of any particular package can include hundreds or thousands of nodes. Surely it's not reasonable to check each one?

Let's talk about left-pad.

In 2016, an open-source developer named Azer Koçulu lost the name of his kik npm package when npm responded to a trademark request from Kik the company. In response, Koçulu removed all 273 of his modules from npm. Suddenly, companies all around the world were running into the same error when trying to build their software:

npm ERR! 404 'left-pad' is not in the npm registry.

These companies weren't even necessarily explicitly depending on left-pad (an 11-line function) but were implicitly depending on it via depending on larger packages such as React. Within 2 hours, npm made the decision to restore the package to benefit the needs of the many, but the event stands as a reminder of the adverse effects of "dependency hell". Sure, it's unlikely a package will go completely missing, but it may introduce a security vulnerability, double in size, make a breaking change, get slower to run, or take too long to update to the latest version of your main framework.

Sometimes, there's just something not quite right about your date's friends. Whether it's flatmap-stream Fred, who tries to steal your wallet, or left-pad Laura, who goes mysteriously missing right when you need her.

Luckily, in the software world, it's becoming more realistic to expect packages to have zero dependencies. For example, lodash, commander, and date-fns are examples of hugely popular packages that don't require you to depend on anything other than themselves. react and rxjs aren't far behind, with tiny dependency chains.

Too Much Baggage

image.png

The server has taken your drinks order, and the conversation is flowing. However, before you know it, your date is telling you all about their ex, how their family has a history of irritable bowel syndrome, and that they don't know why you're on a date with them at all. This is basically Moment.js. In fact, Moment's README says "Moment.js is a legacy project, now in maintenance mode. In most cases, you should choose a different library." - it might as well be telling you that it's not good enough for you and you should go date someone else instead.

So what are the problems with Moment.js? How does it introduce itself on its first date? They actually have a page describing all the reasons you shouldn't install it, but the main reason is that it is simply too big. With the help of Bundlephobia, we can see that moment has a minified + gzipped size of 72.1kB, over three times the size of one of its alternatives: date-fns, which bundles to 19.5kB. That difference may seem small, but it's the equivalent of an extra second download time on a slow 3G network, and performance is important for user experience, retaining users, and improving conversions.

Not all packages will advertise their flaws, so it's important to do some investigation. Bundlephobia will let you preview how much space the new package is going to take up, and regularly running commands like npm audit will give you a heads up on any security vulnerabilities in your dependency tree. Some reasons to reject a package can be more nuanced. In fact, one reason that Moment.js lists itself as legacy is that it uses a mutable API, instead of an immutable one. Coding paradigm decisions like this may also influence your choice.

Stuck in the Past

image.png

The main course arrives and things are going well. You lean forwards and rest your elbows on the table. "Don't do that - it's rude!", your date scoffs. You politely explain the outdatedness of the "no elbows on the table" etiquette and continue to eat. Your date looks on in horror.

You think back to the command you were about to run before you went on your date: npm install jquery. Harmless, right? You know that you can access DOM elements already with getElementById(id), but jQuery lets you do that with $(selector), AND jQuery makes sure that it works on IE6, as getElementById isn't reliable in that version of Internet Explorer. You obviously wouldn't want your site to break on IE6. Although... you struggle to think who even uses IE6 anymore, then sigh as your date pulls out a Nokia 3220.

Like your date, jQuery is stuck in the past.

That's not to say that jQuery wasn't a massively useful and influential library in its day. In fact, it was so useful that so much of its functionality is now baked into modern browsers. On jQuery's home page (which, let's admit, looks as old as your date), they advertise their key selling points as:

  • DOM Traversal and Manipulation
  • Event Handling
  • Ajax

This is all clearly important functionality, but, as illustrated well by YouMightNotNeedjQuery.com, these days there are built-in alternatives in vanilla JavaScript that work just as well.

jQuery boasts an impressive range of cross-browser fixes, making it an extremely portable library. However, these days it is more efficient to use tools like Babel combined with browserslist to choose what browsers you want to support and have only the needed polyfills injected automatically. This lets you avoid increasing your bundle size unnecessarily, and lets you migrate away from older browsers as they become legacy. caniuse.com is a great resource for checking which browsers support particular built-in functionality.

Understanding vanilla JavaScript and the ever-evolving native browser API (instead of jQuery's version of it) is a key skill for front-end development, and that knowledge will always be useful, even as various frameworks rise and fall in popularity.

A Completely Closed Book

You've moved on from your last date, and now you're sitting in a different restaurant with someone new. The staff are collecting the plates from your main course. "It's refreshing," you think to yourself, "to not be dating someone with the specific qualities of a JavaScript package." Maybe you have a type. Your server asks you if you'd like to see the dessert menu. You realize that you don't actually know much about your date. They never truly opened up for the whole meal and are now just staring blankly. You told them everything about yourself but got nothing in return.

Would you let someone into your life if you knew nothing about them? Would you install a package into your project if you didn't know what it did? Luckily, these days, open-source is the norm, rather than the exception. Now, pretty much every popular package and framework is open-source, meaning that users can comb through the source code, raise issues, and even follow contribution guidelines to make their own improvements.

This wasn't always the case. As an avid C# fan, my go-to example of this is always .NET Framework. I'm a firm believer that C# is a more powerful general-purpose language than Java, but for years it was hard to convince people this was the case. It didn't help that Microsoft had a bad reputation for only supporting Windows operating systems and keeping all of their proprietary code closed-source. With the existence of OpenJDK, a cross-platform, open-source version of Java released in 2007, I can understand why developers would be hesitant to use the .NET Framework over it.

Fortunately, in 2014, Microsoft announced that their new project .NET Core (now just called .NET) was going to be both cross-platform AND open-source. This ground-up rewrite paved the way for significant improvements to both C# and its ecosystem, and also set a trend for Microsoft to continue to open-source more and more projects. While I was already on the C# train, this move caused a surge in popularity in both .NET Core and ASP.NET Core (the .NET Core web framework).

image.png

Survey results from the Stack Overflow 2021 survey: Most popular web frameworks for professional developers.

Just like people, exposing our source code allows for more productive relationships.

You think about whether you want to date the closed-source .NET Framework. "I don't have room for dessert", you lie to the server, before asking for the bill.


So, what have we learned?

When choosing whether to install a package in the tech world:

  • Be cautious of unproven packages with low popularity.
  • Try to avoid picking packages that themselves have lots of dependencies.
  • Consider the bundle size and the API of a package.
  • Try to choose packages that are current and still relevant.
  • Prefer open-source packages to closed-source ones.

In the dating world:

  • Don't invite strangers to your house.
  • Do your best to get along with your date's friends.
  • Watch out for dates immediately making their baggage your baggage.
  • Don't waste your time on people with outdated views.
  • Be cautious around people that don't tell you much about themselves.

One of these lists is more useful than the other 🙈.

Thanks for reading! What are your policies for picking a new package to install? Have you ever run into any pitfalls after choosing a certain package?