DEV Community

loading...
Cover image for How I brought down my project's dependency tree from 36 packages to 4 packages

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

saurabhdaware profile image Saurabh Daware 🌻 Updated on ・3 min read

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

Discussion (17)

Collapse
tyrrrz profile image
Alexey Golub

Just make sure to cover all of your handwritten functionality with tests now

Collapse
saurabhdaware profile image
Saurabh Daware 🌻 Author

yes working on it :D thanks for reading 🌻

Collapse
johanalkstal profile image
Johan Alkstål

This is the right kind of thinking. Thumbs up.

Collapse
saurabhdaware profile image
Collapse
jamesthomson profile image
James Thomson

I'll always have a look through a packages dependencies list before considering adding it to a project.

A tool that's helpful when doing this: bundlephobia.com

Collapse
saurabhdaware profile image
Saurabh Daware 🌻 Author

Oh I didn't know about bundlephobia thank you for sharing

Collapse
pavelloz profile image
Paweł Kowalski

Good investigation and solution from your part.

Its so refreshing to see someone caring about how much junk they ship with the app.

I hope more people will take care about it.

Collapse
saurabhdaware profile image
Saurabh Daware 🌻 Author

Thank you so much🌻🌻 and yes every developer should spend some time deciding what frameworks or libraries are actually needed :D

Collapse
zaidrehman profile image
Zaid Rehman • Edited

I used almost a similar approach to remove lodash completely from my project 😅😅

Personally I feel it's a right approach.

Collapse
saurabhdaware profile image
Saurabh Daware 🌻 Author

Do you have a link to this commit or PR? Would love to see how you did :D

Collapse
zaidrehman profile image
Zaid Rehman

Sorry bro it was a private repo of my employer.

Thread Thread
saurabhdaware profile image
Saurabh Daware 🌻 Author

oh ok no problem. good job though :D

Collapse
azeem2793 profile image
Agha Azeem

👍 that’s brilliant

Collapse
saurabhdaware profile image
Saurabh Daware 🌻 Author

thank you so much :D

Collapse
syntaxseed profile image
SyntaxSeed (Sherri W)

I do the same with my PHP dependencies. I give preference to packages without a ton of sub dependencies.

Collapse
saurabhdaware profile image
Saurabh Daware 🌻 Author

Yes I feel this is right approach and applies to any domain and any language and even on the frontend

Forem Open with the Forem app