Skip to content

Pin All NPM Dependencies to Exact Versions

Pin All NPM Dependencies to Exact Versions ​

INFO

This document represents an architecture decision record (ADR) and has been mirrored from the ADR section in our Shopware 6 repository. You can find the original version here

Context ​

NPM dependencies with range specifiers (e.g., ^1.2.3 or ~1.2.3) allow automatic updates to newer compatible versions during installation. While convenient for library development, this creates several risks for application development:

  1. Non-Deterministic Builds: Different developers or CI runs may install different versions, leading to "works on my machine" issues
  2. Security Risk Window: Malicious packages can be introduced through automatic version updates without explicit review
  3. Breaking Changes: Even minor/patch updates can introduce bugs or breaking changes despite semantic versioning
  4. Difficult Debugging: Inconsistent dependency versions across environments make issues harder to reproduce and diagnose

Decision ​

All NPM dependencies in Shopware 6 must be pinned to exact versions without range specifiers:

  • ❌ "package": "^1.2.3" or "package": "~1.2.3"
  • ✅ "package": "1.2.3"

This applies to both dependencies and devDependencies in all package.json files throughout the repository.

Automated CI checks have been implemented to:

  • Discover all package.json files in the repository
  • Validate that no unpinned dependencies exist
  • Block merges if unpinned dependencies are found

These checks run via the npm-audit-check.yml workflow. Pull requests and pushes to trunk run audits only for tracked packages whose package.json, package-lock.json, or scripts/runNpmAudit.ts changed. Scheduled and manual runs still execute the full audit matrix for all tracked packages, and scheduled audit failures create or update one GitHub issue with the latest affected packages.

Consequences ​

Positive ​

  • Reproducible Builds: Identical dependency versions across all environments (local, CI, production)
  • Explicit Updates: Dependency updates require intentional changes and code review
  • Enhanced Security: Prevents automatic installation of compromised package versions
  • Easier Debugging: Consistent versions make issues reproducible and easier to diagnose
  • Automated Enforcement: CI pipeline ensures compliance without manual review

Negative ​

  • Manual Dependency Updates: Developers must explicitly update dependencies using npm update or npm install package@version
  • Increased Maintenance: Regular dependency updates require more conscious effort
  • More Frequent PRs: Security patches and updates must be applied through explicit pull requests

For Developers ​

When adding or updating dependencies:

  1. Always specify exact versions in package.json
  2. Run npm install to update package-lock.json
  3. The CI pipeline will reject PRs with unpinned dependencies
  4. Use tools like npm outdated to check for available updates

Updates ​

  • 2025-11-15: PR audit run with pinned dependencies only, not on all npm packages in repository
Was this page helpful?
UnsatisfiedSatisfied
Be the first to vote!
0.0 / 5  (0 votes)