Installing packages with npm
Adding a package to a project is straightforward with the npm install command (or npm i for short), followed by the package name. For instance, the Node package for Sass is named sass, so running the command from a project folder starts the installation process:
npm install sass
npm then searches the registry for the package and installs it, along with any dependencies that package needs to run. That's why installing Sass may result in many more packages being added than just the one you requested:

After the command finishes, you'll notice three new items in the project folder: package.json, package-lock.json, and a node_modules directory.

Here's what each of these does.
The two JSON files
package.json and package-lock.json work together to record your project's dependencies. The lockfile is a precise, complete snapshot of the entire dependency tree–including all nested dependencies–while package.json provides a higher-level overview and can contain other project metadata. The lockfile should never be edited by hand; only npm updates it.
Both files are meant to be committed to your Git repository. They serve as the dependency blueprint so that other developers cloning the project can run npm install and replicate the exact same environment.
If you open package.json after installing Sass, you'll see the package listed inside a dependencies object, along with the installed version:
{
"dependencies": {
"sass": "^1.43.4"
}
}
The ^ character before the version number is important. It tells npm that the package must be at least the specified version, but minor updates are allowed–for example, any 1.x.x version above 1.43.4, but not 2.0.0. This is part of semantic versioning, a convention npm uses to signal which updates are non-breaking.
The node_modules directory
node_modules is where the actual package code lives. Opening it will reveal a sass folder, but also many others–those are the dependencies Sass requires, and their own dependencies, and so on up the chain. Projects can easily end up with hundreds of subfolders here, consuming a significant amount of disk space.
Unlike the JSON files, node_modules is not meant to be committed to Git. It's standard practice to list it in a .gitignore file so it's never tracked. Teammates get their own copy by running npm install themselves, downloading directly from the registry.
Should you worry about dependencies?
It can feel unsettling that one package installation can pull in dozens of others. But there are good reasons this isn't as risky as it sounds:
- Most npm packages are open source. You can inspect the code, check install counts, and see maintenance activity on the npm registry before using a package. Popular packages are reasonably safe bets.
- Many packages solve common problems. Date formatting, HTTP handling, throttling, and animation are all examples of functionality that many projects need. Reusing well-tested code makes more sense than rewriting it each time.
- This pattern is widespread. Mobile apps and CMS plugins also depend on smaller libraries behind the scenes–you just don't see it the way you do with npm.
That said, caution is still warranted when installing any code that executes on your machine. Stick to popular, well-maintained packages when in doubt. Also, npm performs automatic security audits that can surface known issues.
Dealing with audit warnings
When you run npm install, an audit runs automatically. If any packages have known vulnerabilities, you'll see a report:

Not all warnings are urgent; many moderate vulnerabilities only apply in highly specific conditions. But it's still wise to address them. The npm audit fix command handles this by updating affected packages to the newest minor version, which should not include breaking changes:
npm audit fix --force
The --force flag takes this further by allowing major version updates. This is riskier, because major updates can introduce breaking changes or incompatibilities. Reserve this for critical vulnerabilities that a minor-version fix can't resolve, and only if you're prepared to troubleshoot afterward.
On a related note, when a project starts behaving unexpectedly, a common fix is deleting node_modules and running npm install again. It's the npm equivalent of turning it off and back on.



