How I brought down my project's dependency tree from 36 packages to 4 packages

Saurabh Daware 🌻 - Sep 22 '19 - - Dev Community

Before you npm install package or <script src="https://coolframework.com/file.js"> do you ever ask yourself if you really need this package/framework/library?

Is there any way I can implement the same thing with my own functions?

If the package has 300 functions and I need 2 functions then is it really worth having it in my dependencies?

I did not ask these questions to myself when I started with my project called ProjectMan and installed 3 packages Commander.js, Inquirer.js, and Chalk.

But that ended up putting 36 packages in my dependency tree! So npm install -g projectman was installing 37 packages. What if any one of these packages break down? Do I really need to make people install 36 packages to run my simple command-line tool? More packages = More time to npm install and what if anyone cancels the install?

So after v1.2.0, I decided that I would minimize this size as much possible for v1.3.0 of ProjectMan and started replacing my dependencies one by one.

Target 1 :: Chalk

It is a library to color text on the console.

It has 6 dependencies (including direct and indirect dependencies)

But I didn't really want rainbows flowing through the console of my users 🌈 I just wanted few colors.. so I simply checked what chalk.bold.red("HelloWorld") returns and it returned this horrible looking string:

`\u001b[1m\u001b[31mHelloWorld\u001b[39m\u001b[22m`

As you can see there's HelloWorld inside this string I tried replacing it with other text and it still worked. I did the same thing with all the colors I was using and simply created a colors.js file in my project that now looks something like

// Just some weird strings that color text inside it. You probably will not have to touch this file.

exports.green = (message) => `\u001b[32m${message}\u001b[39m`;    

exports.boldGreen = (message) => `\u001b[1m\u001b[32m${message}\u001b[39m\u001b[22m`;

exports.boldRed = (message) => `\u001b[1m\u001b[31m${message}\u001b[39m\u001b[22m`;

exports.yellow = (message) => `\u001b[33m${message}\u001b[39m`;

exports.boldYellow = (message) => `\u001b[1m\u001b[33m${message}\u001b[39m\u001b[22m`;

exports.grey = (message) => `\u001b[90m${message}\u001b[39m`;

exports.boldGrey = (message) => `\u001b[1m\u001b[90m${message}\u001b[39m\u001b[22m`;

exports.bold = (message) => `\u001b[1m${message}\u001b[22m`;

These 17 lines (including line breaks and comments) replaced 7 packages!!!

And Boom my package was down to 30 dependencies.

Here are changes that I made in repository to achieve this:
https://github.com/saurabhdaware/projectman/commit/413355b41d87ff18c9dcf02bebf51d3da35372b3

Target 2 :: Inquirer.js

Inquirer provides beautiful interfaces for taking input in the form of lists, text and so many other options.

I personally loved this library but the only thing that was bothering me was the dependencies it came up with. Inquirer is dependent on 28 packages (including direct and indirect dependencies). Even for the features inquirer provided, 28 packages were too much!

There was no way I could implement it with my own functions since it has way too many features and it was not possible for me to code all these features.

So I started looking around for alternatives and found prompts.

Prompts can do almost everything that inquirer can and has dependencies of 3 packages (including direct and indirect)!! Although I felt like some of the functions of prompts are not as stable as inquirer but for my case, it worked after some minor workarounds.

And Boom 4 packages replaced 29 packages! ProjectMan was down to 5 packages!!!

Commander.js

Commander is an amazing library and has 0 dependencies so I still use it and I totally love it!

Conclusion

My package runs exactly the same on 4 dependencies as it did on 36 dependencies and did not cost me any scalability issue or bug or breakdown of any major feature.

Before you install a script/package/framework just wait a minute and ask yourself these three questions

  • Do I really need this library?
  • What functions do I need? Is there any way I can write my own function without putting a lot of time and without costing scalability or other issues?
  • If I can't write own function then is there any other stable alternative package that uses lesser dependencies and does not break anything from your package?

Also,

I am not against any of these libraries, There are particular cases where you may actually need a lot of functionality from these libraries and you should totally use them in that case.

Thank you for reading! Do comment and let me know your thoughts about this :D

Twitter: @saurabhcodes
Github: @saurabhdaware
ProjectMan Repo: /saurabhdaware/projectman

. . . . . . . . . . . . . . . . . . .
Terabox Video Player