Dependency Management Overview
Comprehensive dependency management across JavaScript/Node.js, Python, Ruby, Java, and other ecosystems. Covers version control, conflict resolution, security auditing, and best practices for maintaining healthy dependencies.
When to Use Installing or updating project dependencies Resolving version conflicts Auditing security vulnerabilities Managing lock files (package-lock.json, Gemfile.lock, etc.) Implementing semantic versioning Setting up monorepo dependencies Optimizing dependency trees Managing peer dependencies Instructions 1. Package Manager Basics Node.js / npm/yarn/pnpm
Initialize project
npm init -y
Install dependencies
npm install express npm install --save-dev jest npm install --save-exact lodash # Exact version
Update dependencies
npm update npm outdated # Check for outdated packages
Audit security
npm audit npm audit fix
Clean install from lock file
npm ci # Use in CI/CD
View dependency tree
npm list npm list --depth=0 # Top-level only
Python / pip/poetry
Using pip
pip install requests pip install -r requirements.txt pip freeze > requirements.txt
Using poetry (recommended)
poetry init poetry add requests poetry add --dev pytest poetry add "django>=3.2,<4.0" poetry update poetry show --tree poetry check # Verify lock file
Ruby / Bundler
Initialize
bundle init
Install
bundle install bundle update gem_name
Audit
bundle audit check --update
View dependencies
bundle list bundle viz # Generate dependency graph
- Semantic Versioning (SemVer)
Format: MAJOR.MINOR.PATCH (e.g., 2.4.1)
// package.json version ranges { "dependencies": { "exact": "1.2.3", // Exactly 1.2.3 "patch": "~1.2.3", // >=1.2.3 <1.3.0 "minor": "^1.2.3", // >=1.2.3 <2.0.0 "major": "*", // Any version (avoid!) "range": ">=1.2.3 <2.0.0", // Explicit range "latest": "latest" // Always latest (dangerous!) } }
Best Practices:
^ for libraries: allows backward-compatible updates ~ for applications: more conservative, patch updates only Exact versions for critical dependencies Lock files for reproducible builds 3. Dependency Lock Files package-lock.json (npm) { "name": "my-app", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-...", "dependencies": { "body-parser": "1.20.1" } } } }
Lock File Rules:
✅ Always commit lock files to version control ✅ Use npm ci in CI/CD (faster, more reliable) ✅ Regenerate if corrupted: delete and run npm install ❌ Never manually edit lock files ❌ Don't mix package managers (npm + yarn) poetry.lock (Python) [[ package ]] name = "requests" version = "2.28.1" description = "HTTP library" category = "main" optional = false python-versions = ">=3.7"
[ package.dependencies ] certifi = ">=2017.4.17" charset-normalizer = ">=2,<3"
- Resolving Dependency Conflicts Scenario: Version Conflict
Problem: Two packages require different versions
package-a requires lodash@^4.17.0
package-b requires lodash@^3.10.0
Solution 1: Check if newer versions are compatible
npm update lodash
Solution 2: Use resolutions (yarn/package.json)
{ "resolutions": { "lodash": "^4.17.21" } }
Solution 3: Use overrides (npm 8.3+)
{ "overrides": { "lodash": "^4.17.21" } }
Solution 4: Fork and patch
npm install patch-package npx patch-package some-package
Python Conflict Resolution
Find conflicts
pip check
Using pip-tools for constraint resolution
pip install pip-tools pip-compile requirements.in # Generates locked requirements.txt
Poetry automatically resolves conflicts
poetry add package-a package-b # Will find compatible versions
- Security Vulnerability Management npm Security Audit
Audit current dependencies
npm audit
Show detailed report
npm audit --json
Fix automatically (may introduce breaking changes)
npm audit fix
Fix only non-breaking changes
npm audit fix --production --audit-level=moderate
Audit in CI/CD
npm audit --audit-level=high # Fail if high vulnerabilities
Using Snyk
Install Snyk CLI
npm install -g snyk
Authenticate
snyk auth
Test for vulnerabilities
snyk test
Monitor project
snyk monitor
Fix vulnerabilities interactively
snyk wizard
Python Security
Using safety
pip install safety safety check safety check --json
Using pip-audit (official tool)
pip install pip-audit pip-audit
- Monorepo Dependency Management Workspace Structure (npm/yarn/pnpm) // package.json (root) { "name": "my-monorepo", "private": true, "workspaces": [ "packages/", "apps/" ] }
Install all dependencies
npm install
Add dependency to specific workspace
npm install lodash --workspace=@myorg/package-a
Run script in workspace
npm run test --workspace=@myorg/package-a
Run script in all workspaces
npm run test --workspaces
Lerna Example
Initialize lerna
npx lerna init
Bootstrap (install + link)
lerna bootstrap
Add dependency to all packages
lerna add lodash
Version and publish
lerna version lerna publish
- Peer Dependencies // library package.json { "name": "my-react-library", "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" }, "peerDependenciesMeta": { "react-dom": { "optional": true // Makes peer dependency optional } } }
When to Use Peer Dependencies:
Plugin architecture (webpack plugins, babel plugins) React/Vue component libraries Framework extensions Prevents multiple versions of same package 8. Performance Optimization Reduce Bundle Size
Analyze bundle size
npm install -g bundle-buddy npm install --save-dev webpack-bundle-analyzer
Use production build
npm install --production
Prune unused dependencies
npm prune
Find duplicate packages
npm dedupe npx yarn-deduplicate # For yarn
package.json Optimization { "dependencies": { // ❌ Don't install entire lodash "lodash": "^4.17.21",
// ✅ Install only what you need
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1"
} }
- CI/CD Best Practices
.github/workflows/ci.yml
name: CI on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
# Cache dependencies
- uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# Use ci command (faster, more reliable)
- run: npm ci
# Security audit
- run: npm audit --audit-level=high
# Check for outdated dependencies
- run: npm outdated || true
- run: npm test
- Dependency Update Strategies Automated Updates (Dependabot)
.github/dependabot.yml
version: 2 updates: - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" open-pull-requests-limit: 10 groups: dev-dependencies: dependency-type: "development" ignore: - dependency-name: "react" versions: ["17.x"]
Manual Update Strategy
Step 1: Check outdated
npm outdated
Step 2: Update dev dependencies first
npm update --save-dev
Step 3: Test thoroughly
npm test
Step 4: Update production deps (one by one for major updates)
npm update express
Step 5: Review changelog
npm view express versions npm view express@latest
Best Practices ✅ DO Commit lock files to version control Use npm ci or equivalent in CI/CD pipelines Regular dependency audits (weekly/monthly) Keep dependencies up-to-date (automate with Dependabot) Use exact versions for critical dependencies Document why specific versions are pinned Test after updating dependencies Use semantic versioning correctly Minimize dependency count Review dependency licenses ❌ DON'T Manually edit lock files Mix package managers (npm + yarn in same project) Use npm install in CI/CD (use npm ci) Ignore security vulnerabilities Use wildcards (*) for versions Install packages globally when local install is possible Commit node_modules to git Use latest tag in production Blindly run npm audit fix Install unnecessary dependencies Common Patterns Pattern 1: Strict Version Control { "dependencies": { "critical-package": "1.2.3", // Exact version "stable-package": "~2.3.4" // Patch updates only }, "engines": { "node": ">=16.0.0 <19.0.0", "npm": ">=8.0.0" } }
Pattern 2: Optional Dependencies { "optionalDependencies": { "fsevents": "^2.3.2" // macOS only, won't break on other OS } }
Pattern 3: Custom Registry
.npmrc
registry=https://registry.npmjs.org/ @myorg:registry=https://npm.pkg.github.com/
Or scoped
npm install --registry=https://custom-registry.com/
Tools & Resources npm: Default Node.js package manager Yarn: Fast, reliable, secure dependency management pnpm: Efficient disk space usage, strict node_modules Poetry: Modern Python dependency management Bundler: Ruby dependency management Snyk: Security vulnerability scanning Dependabot: Automated dependency updates Renovate: Advanced dependency update automation npm-check-updates: Interactive dependency updates Quick Reference
Check versions
node --version npm --version
Clear cache if issues
npm cache clean --force yarn cache clean pnpm store prune
Reinstall all dependencies
rm -rf node_modules package-lock.json npm install
Why is this dependency installed?
npm ls package-name yarn why package-name
Find security issues
npm audit snyk test
Update all dependencies to latest
npx npm-check-updates -u npm install