Over dependance - the ‘npm install’ trap

Tom Riglar
May 23, 2019 · 4 min read

We’ve all been there. It’s late. The coffee has run out. The feature you’re working on is destined for the next release. Don’t reinvent the wheel you tell yourself, there must be a library that will do most of the work for me! And there probably is…

The JavaScript ecosystem is huge. NPM alone has over 800k packages. Everything from tiny comedy packages such as is-thirteen to industry titans like React. Typing npm install is easy — but what are the longer term consequences for introducing so many dependancies? Here are five traps you might fall into.

1. The peer dependancy trap

A peer dependancy is a package that is depended on by a third party package that you must provide yourself. For example, react-router-dom has a peer dependancy on React. When you npm install react-router-dom you won’t also get React. You’ll have to install React separately and ensure a compatible version is available for react-router-dom to use.

oh no!

The peer dependancy trap occurs when you have two different packages that require different versions of the peer dependancy. Let’s walk through the scenario:

  • You install framework-a v1 to render DOM for you.
  • You install package-x to render text inputs for you, it needs framework-a v1 as a peer dependancy.
  • You install package-y to render select inputs for you, it also needs framework-a v1 as a peer dependancy.
  • Disaster strikes! It turns there is a bug in package-c, so you download the new version from NPM. But times have moved on and now package-y needs framework-a v2 as a peer dependancy. Unfortunately, package-x still only works with framework-a v1 so you are stuck!

Sure, with just a few packages you can often mitigate this risk. However, for each package you add that has a peer dependancy the chances of this happening can become very real.

2. The ‘I’m too busy to maintain this’ trap

This point boils down to one key word: maintenance. If a bug crops up or a feature is required in a package you depend on then you’ve got a few options:

  • Get the author to publish the fix or feature.
  • Submit a pull request and get the author to merge it and publish.
  • Fork the package, make the changes and use your fork.

Two of those options leave your fate in the hands of the maintainer. The third option raises lots of new questions. Who maintains the fork? What happens if the original package releases a new feature I want?

A quick fix isn’t always in sight…

3. The support trap

Some documentation is great but in the NPM wild west a lot is often left desired. Often the happy path is well supported, but as soon as you stray to an edge case you’re left on your own. The longer term consequence is that when you re-visit the integration in six months’ times you’re going to have a hard time understanding what is going on.

4. The responsibility burden

NPM modules are in their own special folder, away from your source code. Out of sight, out of mind, right? Wrong.

When you integrate a library, you are committing to including that library’s code in your final product. That code is likely open source, but ultimately it is outside of your control. This can undermine good intentions you might have in own source code. Some examples:

  • Your 99% code coverage isn’t so impressive if 90% of your code is NPM modules with poor code coverage.
  • Your strictly scoped CSS can quickly be undermined by a third party global selector.

Library code is almost always provided without an guarantee. That means that when something goes wrong, the buck stops with you.

5. The secondary dependancy burden

Most modules you install will have dependancies on other modules. These will dutifully be installed by NPM along with the dependant itself. The are two potential pitfalls here.

The first is that every module required by the module you just installed may also depend on other modules. This tree of dependancies could have quite a few levels and end up adding huge chunks of code to your app. Ultimately, any one of those modules could succumb to the issues highlighted above.

Secondly, if you are packaging JS for the frontend, each additional module results in a bundle size increase. For high performance apps, this can increase load time and degrade user experience.

Conclusion

For the best that NPM has to offer, the rewards can often outweigh the risks listed above. For everything else, think twice before you npm install

Tom Riglar

Written by

CEO of App Sapiens | We are team of expert software developers and technologists headquartered in the UK.

App Sapiens

Expert knowledge, modern technology

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade