DEV Community

Cover image for About Modules...
Garrin Costa, Jr.
Garrin Costa, Jr.

Posted on

About Modules...

I want to talk about modules in software development. Specifically Node.js modules and some of the core concepts around them.
I first want to offer a bit of transparency: I am a software development student of about 8 months. I often feel like I'm flailing in a sea of new information and abstract concepts, struggling to fully comprehend, retain, and reproduce them. This might be a clumsy journey up and down the dependency tree.

Why write about something I don't feel qualified to write about?

My cohort and I recently started our thesis project. During the initial setup stage, I made a point to walk through it with more intention than I had previously. I don't like the feeling of using tools I don't understand. I don't like feeling unstable and obstructed, or that something could collapse at any moment due to my lack of knowledge. Writing about it now is sort of like extending that deliberate walk through the setup stage. It's pushing me to circle back on the topic and get in the weeds like I did then (and I did get in the weeds). But doing so opened up opportunities for my teammates and me to collaborate and make thoughtful, intentional decisions for our project and how we would be building it.

When my team and I initialized our thesis repo, one of the first things I wanted to get clarity on was the config files sitting at the root. For a long time, package.json was a bit murky. I understood most of what I was looking at but there were some aspects of it that were still only conjecture. While package-lock.json was – and to a degree, still is – much less understood.

To really feel stable in our setup (or any repository in which I might find myself), I had to stop avoiding confrontation with my own ignorance.

My findings so far

Think of package.json as the manifest or wishlist. It lists the top-level packages your app needs, but it relies on Semantic Versioning (SemVer). When you see something like "express": "^4.18.2", that caret (^) means: "Give me version 4.18.2, or any backward-compatible patch or minor update released in the future."

This kind of flexibility sounds good in theory, but it creates potential problems for team projects. Let's say I run npm install today and my teammate runs npm install a week from now. If a minor sub-dependency happens to release a patch in between our two separate installs, our environments end up running slightly different software, which is not something we want happening.

Thankfully, with package-lock.json, we get an exact snapshot of the entire dependency tree.

package-lock.json records every sub-dependency, the exact version, where it was fetched from, and even a cryptographic hash (integrity) to verify the download hasn't been tampered with.

By committing package-lock.json to Git, my team guarantees that everyone gets the exact same node_modules tree on every machine, avoiding mysterious updates and environment drift.

But wait! If package-lock.json gets rewritten when you run npm install, how does it protect you?

This tripped me up at first, and probably still does. It's starting to sink in though.

The key distinction is that npm install reads the lockfile first. When a teammate pulls down the repo and runs npm install, npm checks if the existing package.json constraints are satisfied by what's written in package-lock.json. When they are, it bypasses the newest registry releases and reproduces the exact versions recorded in the lockfile without rewriting it.

It only modifies package-lock.json when you explicitly demand a change, like running npm install <new-package>, or manually editing a version range in package.json that the current lockfile can't satisfy.

For even stricter guarantee on team setups or CI/CD pipelines, there’s npm ci (Clean Install). Unlike npm install, npm ci ignores available updates and does not modify package-lock.json. It will also throw a hard error if package.json and the lockfile ever get out of sync.

To be continued...

Top comments (0)