Common Misconfigurations
- Using caret (^) or tilde (~) ranges in production
- Not committing package-lock.json
- Using latest tag or * for versions
- Inconsistent versioning strategies
- Not using exact versions for critical dependencies
Vulnerable Example
Secure Solution
Key Commands for Pinning and Updating
While the goal is to pin versions, you still need commands to manage these pins and update them securely.1. Installing Packages with Exact Versions
To install a new package and automatically pin its exact version inpackage.json, use the --save-exact flag:
.npmrc file (as shown in the Secure Solution):
2. Enforcing Pinned Versions (CI/CD)
This command is crucial for CI/CD. It installs dependencies exactly as specified in yourpackage-lock.json file. It’s faster and more reliable than npm install as it doesn’t try to resolve versions.
3. Creating a Shrinkwrap File
If you are publishing a library or need an even stricter lockfile that gets published, you can usenpm shrinkwrap. This creates an npm-shrinkwrap.json file (which is just a renamed package-lock.json) that takes precedence.
4. Checking for Updates (When Pinned)
When all your versions are pinned,npm outdated will still show you newer versions, but npm update won’t do anything. You need a dedicated tool to manage updates.
The npm-check-updates tool is perfect for this. It checks for the latest versions and can update your package.json file for you.
Best Practices
- Use exact versions for production dependencies.
- Always commit
package-lock.json. - Configure
save-exactin.npmrc. - Use
npm ciinstead ofnpm installin CI/CD. - Implement a controlled update process with tools like Renovate.

