Dependency Upgrade
Master major dependency version upgrades, compatibility analysis, staged upgrade strategies, and comprehensive testing approaches.
Do not use this skill when
- •The task is unrelated to dependency upgrade
- •You need a different domain or tool outside this scope
Instructions
- •Clarify goals, constraints, and required inputs.
- •Apply relevant best practices and validate outcomes.
- •Provide actionable steps and verification.
- •If detailed examples are required, open
resources/implementation-playbook.md.
Use this skill when
- •Upgrading major framework versions
- •Updating security-vulnerable dependencies
- •Modernizing legacy dependencies
- •Resolving dependency conflicts
- •Planning incremental upgrade paths
- •Testing compatibility matrices
- •Automating dependency updates
Semantic Versioning Review
code
MAJOR.MINOR.PATCH (e.g., 2.3.1) MAJOR: Breaking changes MINOR: New features, backward compatible PATCH: Bug fixes, backward compatible ^2.3.1 = >=2.3.1 <3.0.0 (minor updates) ~2.3.1 = >=2.3.1 <2.4.0 (patch updates) 2.3.1 = exact version
Dependency Analysis
Audit Dependencies
bash
# npm npm outdated npm audit npm audit fix # yarn yarn outdated yarn audit # Check for major updates npx npm-check-updates npx npm-check-updates -u # Update package.json
Analyze Dependency Tree
bash
# See why a package is installed npm ls package-name yarn why package-name # Find duplicate packages npm dedupe yarn dedupe # Visualize dependencies npx madge --image graph.png src/
Compatibility Matrix
javascript
// compatibility-matrix.js
const compatibilityMatrix = {
'react': {
'16.x': {
'react-dom': '^16.0.0',
'react-router-dom': '^5.0.0',
'@testing-library/react': '^11.0.0'
},
'17.x': {
'react-dom': '^17.0.0',
'react-router-dom': '^5.0.0 || ^6.0.0',
'@testing-library/react': '^12.0.0'
},
'18.x': {
'react-dom': '^18.0.0',
'react-router-dom': '^6.0.0',
'@testing-library/react': '^13.0.0'
}
}
};
function checkCompatibility(packages) {
// Validate package versions against matrix
}
Staged Upgrade Strategy
Phase 1: Planning
bash
# 1. Identify current versions npm list --depth=0 # 2. Check for breaking changes # Read CHANGELOG.md and MIGRATION.md # 3. Create upgrade plan echo "Upgrade order: 1. TypeScript 2. React 3. React Router 4. Testing libraries 5. Build tools" > UPGRADE_PLAN.md
Phase 2: Incremental Updates
bash
# Don't upgrade everything at once! # Step 1: Update TypeScript npm install typescript@latest # Test npm run test npm run build # Step 2: Update React (one major version at a time) npm install react@17 react-dom@17 # Test again npm run test # Step 3: Continue with other packages npm install react-router-dom@6 # And so on...
Phase 3: Validation
javascript
// tests/compatibility.test.js
describe('Dependency Compatibility', () => {
it('should have compatible React versions', () => {
const reactVersion = require('react/package.json').version;
const reactDomVersion = require('react-dom/package.json').version;
expect(reactVersion).toBe(reactDomVersion);
});
it('should not have peer dependency warnings', () => {
// Run npm ls and check for warnings
});
});
Breaking Change Handling
Identifying Breaking Changes
bash
# Use changelog parsers npx changelog-parser react 16.0.0 17.0.0 # Or manually check curl https://raw.githubusercontent.com/facebook/react/main/CHANGELOG.md
Codemod for Automated Fixes
bash
# React upgrade codemods npx react-codeshift <transform> <path> # Example: Update lifecycle methods npx react-codeshift \ --parser tsx \ --transform react-codeshift/transforms/rename-unsafe-lifecycles.js \ src/
Custom Migration Script
javascript
// migration-script.js
const fs = require('fs');
const glob = require('glob');
glob('src/**/*.tsx', (err, files) => {
files.forEach(file => {
let content = fs.readFileSync(file, 'utf8');
// Replace old API with new API
content = content.replace(
/componentWillMount/g,
'UNSAFE_componentWillMount'
);
// Update imports
content = content.replace(
/import { Component } from 'react'/g,
"import React, { Component } from 'react'"
);
fs.writeFileSync(file, content);
});
});
Testing Strategy
Unit Tests
javascript
// Ensure tests pass before and after upgrade npm run test // Update test utilities if needed npm install @testing-library/react@latest
Integration Tests
javascript
// tests/integration/app.test.js
describe('App Integration', () => {
it('should render without crashing', () => {
render(<App />);
});
it('should handle navigation', () => {
const { getByText } = render(<App />);
fireEvent.click(getByText('Navigate'));
expect(screen.getByText('New Page')).toBeInTheDocument();
});
});
Visual Regression Tests
javascript
// visual-regression.test.js
describe('Visual Regression', () => {
it('should match snapshot', () => {
const { container } = render(<App />);
expect(container.firstChild).toMatchSnapshot();
});
});
E2E Tests
javascript
// cypress/e2e/app.cy.js
describe('E2E Tests', () => {
it('should complete user flow', () => {
cy.visit('/');
cy.get('[data-testid="login"]').click();
cy.get('input[name="email"]').type('user@example.com');
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
});
});
Automated Dependency Updates
Renovate Configuration
json
// renovate.json
{
"extends": ["config:base"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
},
{
"matchUpdateTypes": ["major"],
"automerge": false,
"labels": ["major-update"]
}
],
"schedule": ["before 3am on Monday"],
"timezone": "America/New_York"
}
Dependabot Configuration
yaml
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
reviewers:
- "team-leads"
commit-message:
prefix: "chore"
include: "scope"
Rollback Plan
javascript
// rollback.sh #!/bin/bash # Save current state git stash git checkout -b upgrade-branch # Attempt upgrade npm install package@latest # Run tests if npm run test; then echo "Upgrade successful" git add package.json package-lock.json git commit -m "chore: upgrade package" else echo "Upgrade failed, rolling back" git checkout main git branch -D upgrade-branch npm install # Restore from package-lock.json fi
Common Upgrade Patterns
Lock File Management
bash
# npm npm install --package-lock-only # Update lock file only npm ci # Clean install from lock file # yarn yarn install --frozen-lockfile # CI mode yarn upgrade-interactive # Interactive upgrades
Peer Dependency Resolution
bash
# npm 7+: strict peer dependencies npm install --legacy-peer-deps # Ignore peer deps # npm 8+: override peer dependencies npm install --force
Workspace Upgrades
bash
# Update all workspace packages npm install --workspaces # Update specific workspace npm install package@latest --workspace=packages/app
Resources
- •references/semver.md: Semantic versioning guide
- •references/compatibility-matrix.md: Common compatibility issues
- •references/staged-upgrades.md: Incremental upgrade strategies
- •references/testing-strategy.md: Comprehensive testing approaches
- •assets/upgrade-checklist.md: Step-by-step checklist
- •assets/compatibility-matrix.csv: Version compatibility table
- •scripts/audit-dependencies.sh: Dependency audit script
Best Practices
- •Read Changelogs: Understand what changed
- •Upgrade Incrementally: One major version at a time
- •Test Thoroughly: Unit, integration, E2E tests
- •Check Peer Dependencies: Resolve conflicts early
- •Use Lock Files: Ensure reproducible installs
- •Automate Updates: Use Renovate or Dependabot
- •Monitor: Watch for runtime errors post-upgrade
- •Document: Keep upgrade notes
Upgrade Checklist
markdown
Pre-Upgrade: - [ ] Review current dependency versions - [ ] Read changelogs for breaking changes - [ ] Create feature branch - [ ] Backup current state (git tag) - [ ] Run full test suite (baseline) During Upgrade: - [ ] Upgrade one dependency at a time - [ ] Update peer dependencies - [ ] Fix TypeScript errors - [ ] Update tests if needed - [ ] Run test suite after each upgrade - [ ] Check bundle size impact Post-Upgrade: - [ ] Full regression testing - [ ] Performance testing - [ ] Update documentation - [ ] Deploy to staging - [ ] Monitor for errors - [ ] Deploy to production
Common Pitfalls
- •Upgrading all dependencies at once
- •Not testing after each upgrade
- •Ignoring peer dependency warnings
- •Forgetting to update lock file
- •Not reading breaking change notes
- •Skipping major versions
- •Not having rollback plan
🏰 Rei Skills — Curated by Rootcastle Engineering & Innovation | Batuhan Ayrıbaş
Engineering Beyond Boundaries | admin@rootcastle.com