Taking care of your dependencies

2018-12-25 20:31

If you've been working recently with Node (or Javascript in general) you've probably seen many complaints and/or jokes about the infamous weight of node_modules folder.

There're plenty of opinions about this issue. From "It's NPM's fault" to "It's developer's fault". I'm with the latter.

Realization

I've been working with Node for many years now, frontend and backend projects, simple and complicated ones. I'm not sure about many things, but this one is an exception:

We can do much better when handling dependencies.

When you add a dependency to your project, you add a point of failure too, a portion of your project that you can't control anymore, not even when you use package locking. I'm not saying "never add dependencies", but a little bit of code is much better than a little dependency.

Let me tell you something: npm isn't community driven, it's a company. As a company, it have commercial interests. They do what they do just because it's profitable. Companies born and die, because commercial interests born and die too. If you've a dependency as a npm package, and some day npm isn't there anymore (or just the package isn't there anymore), well, your project will not work anymore.

To summarize: The less external dependencies, the better. The probability of a dependency of yours being deleted from npm will be lower, and the amount of external code that you'll probably end up debugging any time, will be lower too.

But today's reality is: We are the ones choosing a bloated library, with millions of dependencies and features, just for using one of them, instead of looking for a more lightweight one. Do one thing and do it well.

We are the ones including a CLI tool framework inside our library "just in case someone needs it as a CLI tool", instead of providing two packages that share a core functionality and build a library API or a CLI on top of it.

We are the ones including data collection mechanisms into our libraries so we can know who is installing it, or where, instead of... just not doing that.

We are the ones needing a library for a left pad or checking if a string is a valid email in a SPA instead of writting it by ourselves.

EDIT: As Waweic suggested, using a good-working external library to check if an email is valid might be the right thing to do in critical environments in terms of security, like a Node.js backend.

Taking action

So you want to take care of your dependencies. Glad to hear!

At this point you should already know what to do, but to summarize:

Test your dependencies

Many dependencies already have their own tests that need to pass before releasing a new version, and you could argue "well, the dependency already have tests, I'll assume that the dependency works", but reality is way more complicated.

The only way to ensure that your project actually works is testing it as a whole, including the dependencies. Or, at least, as many dependencies as you can. It's pretty easy to make tests for dependencies like markdown parsers, cyphers, etc, but it's much harder to test a dependency that is a Twitter client, for example. If you're adding a dependency that is reasonably easy to test, you should consider testing it, even with unit tests.

Let's say that you add a library that manages JWT tokens (building, parsing, validation...) and one day that library gets updated or you decide to change the dependency to use another one that you consider is a better option. Wouldn't be handy to have tests for that? This is because, once you add a dependency to your project, that dependency becomes a functional part of your project, becomes a responsability of yours, that also needs proper testing as any other part of your project.

Testing your dependencies is a way to protect yourself from them, and make them easily replaceable.

The responsible developer's toolkit

I'll leave here the tools I currently use to analyze npm packages before adding them as a dependency. Or to analyze my own projects.

Suggestions are welcome! Make a PR to this article on GitHub or contact with me.

Stay curious, be picky

If there's a npm package that is taking too much size, check its package.json, maybe there's a dependency that isn't really needed because the way you're using the library. You could even open an issue and discuss it with the maintainer, or directly fork the library, remove the unnecesary stuff and upload your own fork to npm (you can prefix them with your username).

Don't be satisfied with the first bloated library you find. Find further, check (and contribute to) awesome lists, search by keyword on npm directly, or check cool projects that do something that you want to do and see how it's done.

Be picky with your dependencies, try to find the best you can, or write your own. Apply to yourself and your projects the same exigence you apply to your dependencies. Be excellent.

This way we can improve the ecosystem and make better and lighter software much easier.