For a long time, the subject of package managers was for me an intimidating one. As a bootcamp grad, I knew enough to build a website or set up a database but any configuration issues stressed me out. Every now and then, I'll encounter a discussion on which package manager is the superior one and I'd immediately feel humbled by all the things I still don't know about web dev.
Now that at StackBlitz we are about to make a big announcement regarding package managers, I thought I'd revisit this topic and take an “Explain like I’m five” route 💕
Let’s look into what a Node module, a package, and a package manager are.
Metaphor: LEGO sets
I have recently visited a friend who loves LEGO. His whole house looks like an exhibition hall with colorful sets displayed in the most surprising places. There’s a flower standing on a bathroom mirror shelf, a dragon guarding the stairs, a TV series set near the kitchen table, and a wizardry school near his TV stand. I’ve noticed that in most cases one big creation was, in fact, a collection of smaller sets.
Imagine that the massive wizardry school castle is your app and for it to be complete, you need to add a bunch of extras like a train station, a magic tree, or a phoenix. Each of them is a separate entity that you can move around as you wish.
Node modules and packages
If the wizardry school castle is your app, then each of the extras would be a Node module or a package.
So your castle needs a magic tree. You could design it yourself but it is way easier get the whole set designed and packaged together in a box with an instruction. A ready-made set in this analogy is a “package” and the instruction is the “
A Node module, or a package, is a piece of code that helps you add some functionality to your app. The
package.json file tells us who created the package, when it was created, what other “dependencies” it needs to function, and so on.
To satisfy the folks who like to be very precise, please note that the npm docs page makes a distinction between "Node modules" and "packages. However, in most cases “Node module” and “package” are used interchangeably.
Now, if you only have one or two LEGO sets in your home, managing an inventory of all the blocks, sets, and figurines you have would not be that difficult. But what if you are a lifelong collector, pieces break often, there are new sets constantly coming out, and the available color scheme changes faster than the company manages to announce it? Well, ideally you would find a system to keep track of all the pieces you own, need to replace, no longer need, and that that you need to buy?
This is why in software there is a need for the so-called “package managers”. A package manager is a tool that helps you keep track of all dependencies of your app in a consistent way. It automates the tasks of dependency installation, upgrading, configuration, and removal. It makes sure that all the packages that your app needs are installed, in the correct version, or up-to-date.
tl;dr package managers automate all the tasks regarding dependencies, saving your precious time 💕
We will share big news regarding package managers at the upcoming ViteConf. Grab your free ticket and tune in this week (Oct 12-13) if you're curious 👀
Latest comments (7)
Thanks so dang much for writing this post! I absolutely love the LEGO analogy and believe that it's helping me to better understand packages and package managing.
One thing that I'm getting a bit tripped up on and thinking you might be able to help me with is what's the difference between a package and a library? Also wondering about how frameworks differ from these as well...
Oh Micheal, how great you are at picking topics that start a great discussion!
*Package is code that you install from somewhere else *- in this sense, both libraries and frameworks are packages. It's like - someone is sending you a gift, you get a package and you call it a "package" regardless of the contents.
Both libraries and frameworks are supposed to make your life easier by adding some functionality to your app. As with many things in web dev world, the answer to define or delineate those two would be "it depends" 😂
I mostly agree with the notion of dividing these helpers in terms of how "opinionated" they are. If it comes with a lot of rules, tools, or if it performs a lot of "magic" for you, it's a framework. Just like a theoretical framework, it imposes a certain lens through which you will look at the problems and solutions. For example, Rails has opinions on everything, for instance, where you should put what. If you do it differently, it may just not work. If you play by the rules, it will do A LOT for you and you won't have to worry about anything. Angular also comes with a lot of tools and performs a lot of heavy lifting for you.
Library, on the other hand, is where you go to to learn and make informed decisions. In his great talk "DOM as a Second-class Citizen", Sebastian Markbåge said that "React gives you tools to build your own toolbox". React is a library and gives the devs the opportunity to build their own abstractions and add whatever tools you need. There's little that comes out of the box. This feels nice because freedom is nice but that's also where the main pain of using React lies - there's way too much freedom and because of that, many codebases look like horror stories. The fact that you can write something doesn't always mean you should.
tl;dr libraries offer you freedom to make your own stuff, frameworks impose a lens.
Let me know how this lands with you!
Quite good explanation.
P.s. Fix the link, please. It's viteconf.org, not viteconf.com :)
Ahhhhh 🙈 thank you!!
I agree that package managers are fine for putting many applications together. Packages do come with the caveat that there is the assumption and trust that all packages are free of malware.
I mostly ascribe to the principle of "small, light, fast, and flat." Packages tend to introduce lots of additional and largely unnecessary dependencies (occasionally with very deep dependency trees) and even the application might only ever use maybe 10% of what the complete package provides. I generally like to cherry-pick the files I need from a package and directly load them, which also helps limit the potential attack surface. Then I use File Tracker to manage/push updates to the relevant subset of files.
I am currently tracking thousands of files across hundred of projects on many systems with that tool. The diff-merging part is what makes it safe to do software updates across hundreds of disparate software projects. File Tracker is not for everyone but it allows for only the used bits of packages to be deployed widely to hundreds of applications and kept up to date with minimal effort.
It takes extra time to sift through a package to cherry-pick specific files and then set up tracking in File Tracker. Perhaps the time is better spent on the application but I am able to easily evaluate whether or not incoming updates/changes to files will break an application before it breaks the application and can then manually intervene as needed. As I said, not for everyone. Package managers are widely used because they tend to enable rapid application development and global deployment and also generally don't present system security issues except on rare occasions. I'm just a bit more picky and security paranoid than most devs.
But sometimes a project just needs to get done and the final project size or app performance or keeping packages updated aren't major concerns (e.g. short-lived, one-off apps that have a shelf life of a month or two). Package managers can be useful here as a notable time saver.
I totally forgot to mention the malware. I'll add it to the metaphor - thank you for the reminder and the writeup!