skills/migrate-ops/SKILL.md
Framework and language migration patterns - version upgrades, breaking changes, dependency audit, safe rollback. Use for: migrate, migration, upgrade, version bump, breaking changes, deprecation, dependency audit, npm audit, pip-audit, codemod, jscodeshift, rector, rollback, semver, changelog, framework upgrade, language upgrade, React 19, Vue 3, Next.js App Router, Laravel 13, Angular, Python 3.14, Node 26, TypeScript 6, Go 1.26, Rust 2024, PHP 8.5.
npx skillsauth add 0xDarkMatter/claude-mods migrate-opsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Comprehensive migration skill covering framework upgrades, language version bumps, dependency auditing, breaking change detection, codemods, and rollback strategies.
Ecosystem facts verified as of 2026-07-05.
What kind of migration are you performing?
│
├─ Small library update (patch/minor version)
│ └─ In-place upgrade
│ Update dependency, run tests, deploy
│
├─ Major framework version (React 18→19, Vue 2→3, Laravel 12→13)
│ │
│ ├─ Codebase < 50k LOC, good test coverage (>70%)
│ │ └─ Big Bang Migration
│ │ Upgrade everything at once in a feature branch
│ │ Pros: clean cutover, no dual-version complexity
│ │ Cons: high risk, long branch life, merge conflicts
│ │
│ ├─ Codebase > 50k LOC, partial test coverage
│ │ └─ Incremental Migration
│ │ Upgrade module by module, use compatibility layers
│ │ Pros: lower risk per step, continuous delivery
│ │ Cons: dual-version code, longer total duration
│ │
│ ├─ Monolith → microservice or complete architecture shift
│ │ └─ Strangler Fig Pattern
│ │ Route new features to new system, migrate old features gradually
│ │ Pros: zero-downtime, reversible, production-validated
│ │ Cons: routing complexity, data sync challenges
│ │
│ └─ High-risk data pipeline or financial system
│ └─ Parallel Run
│ Run old and new systems simultaneously, compare outputs
│ Pros: highest confidence, catch subtle differences
│ Cons: double infrastructure cost, comparison logic
│
└─ Language version upgrade (Python 3.12→3.14, Node 22→26)
└─ In-place upgrade with CI matrix
Test against both old and new versions in CI
Drop old version support once all tests pass
Which framework are you upgrading?
│
├─ React 18 → 19
│ ├─ Check: Remove forwardRef wrappers (ref is now a regular prop)
│ ├─ Check: Replace <Context.Provider> with <Context>
│ ├─ Check: Adopt useActionState / useFormStatus for forms
│ ├─ Check: Replace manual memoization if using React Compiler
│ ├─ Codemod: npx codemod@latest react/19/migration-recipe
│ └─ Load: ./references/framework-upgrades.md
│
├─ Next.js Pages Router → App Router
│ ├─ Check: Move pages/ to app/ with new file conventions
│ ├─ Check: Replace getServerSideProps/getStaticProps with async components
│ ├─ Check: Convert _app.tsx and _document.tsx to layout.tsx
│ ├─ Check: Update data fetching to use fetch() with caching options
│ ├─ Codemod: npx @next/codemod@latest
│ └─ Load: ./references/framework-upgrades.md
│
├─ Vue 2 → 3
│ ├─ Check: Replace Options API with Composition API (optional but recommended)
│ ├─ Check: Replace Vuex with Pinia
│ ├─ Check: Replace event bus with mitt or provide/inject
│ ├─ Check: Update v-model syntax (modelValue prop)
│ ├─ Tool: Migration build (@vue/compat) for incremental migration
│ └─ Load: ./references/framework-upgrades.md
│
├─ Laravel 12 → 13
│ ├─ Check: PHP 8.3 is now the minimum (8.5 supported)
│ ├─ Check: Cache/Redis key prefixes now use hyphenated suffixes
│ ├─ Check: Adopt native PHP attributes (models, jobs, controllers) — optional
│ ├─ Check: Queue routing by class via Queue::route(...) — optional
│ ├─ Tool: laravel shift (automated upgrade service)
│ └─ Load: ./references/framework-upgrades.md (covers 10→11 in depth; 12→13 is near zero-break)
│
├─ Angular (any major version)
│ ├─ Check: Run ng update for guided migration
│ ├─ Check: Review Angular Update Guide (update.angular.io)
│ ├─ Tool: ng update @angular/core @angular/cli
│ └─ Load: ./references/framework-upgrades.md
│
└─ Django (any major version)
├─ Check: Run python -Wd manage.py test for deprecation warnings
├─ Check: Review Django release notes for removals
├─ Tool: django-upgrade (automatic fixer)
└─ Load: ./references/framework-upgrades.md
Ecosystem?
│
├─ JavaScript / Node.js
│ ├─ npm audit / npm audit fix
│ ├─ npx audit-ci --moderate (CI integration)
│ └─ Socket.dev for supply chain analysis
│
├─ Python
│ ├─ pip-audit
│ ├─ safety check
│ └─ pip-audit --fix (auto-update vulnerable packages)
│
├─ Rust
│ ├─ cargo audit
│ └─ cargo deny check advisories
│
├─ Go
│ ├─ govulncheck ./...
│ └─ go list -m -u all (list available updates)
│
├─ PHP
│ ├─ composer audit
│ └─ composer outdated --direct
│
└─ Multi-ecosystem
└─ Trivy, Snyk, or Dependabot across all
[ ] Test coverage measured and documented (target: >70% for critical paths)
[ ] CI pipeline green on current version
[ ] All dependencies up to date (or pinned with rationale)
[ ] Database backup taken (if applicable)
[ ] Git state clean — migration branch created from latest main
[ ] Rollback plan documented and tested
[ ] Breaking change list reviewed from upstream changelog
[ ] Team notified of migration window
[ ] Feature flags in place for gradual rollout (if applicable)
[ ] Monitoring and alerting configured for regression detection
[ ] Performance baseline captured (response times, memory, CPU)
[ ] Lock file committed (package-lock.json, yarn.lock, Cargo.lock, etc.)
How do you detect breaking changes?
│
├─ Semver Analysis
│ ├─ Major version bump → breaking changes guaranteed
│ ├─ Check CHANGELOG.md or BREAKING_CHANGES.md in repo
│ └─ npm: npx npm-check-updates --target major
│
├─ Changelog Parsing
│ ├─ Search for: "BREAKING", "removed", "deprecated", "renamed"
│ ├─ GitHub: compare releases page between versions
│ └─ Read migration guide if one exists
│
├─ Compiler / Runtime Warnings
│ ├─ Enable all deprecation warnings before upgrading
│ ├─ Python: python -Wd (turn deprecation warnings to errors)
│ ├─ Node: node --throw-deprecation
│ └─ TypeScript: strict mode catches type-level breaks
│
├─ Codemods (automated detection + fix)
│ ├─ jscodeshift — JavaScript/TypeScript AST transforms
│ ├─ ast-grep — language-agnostic structural search/replace
│ ├─ rector — PHP automated refactoring
│ ├─ gofmt / gofumpt — Go formatting changes
│ └─ 2to3 — Python 2 to 3 (legacy)
│
└─ Type Checking
├─ TypeScript: tsc --noEmit catches API shape changes
├─ Python: mypy / pyright after upgrade
└─ Go: go vet ./... after upgrade
| Ecosystem | Tool | Command | Use Case |
|-----------|------|---------|----------|
| JS/TS | jscodeshift | npx jscodeshift -t transform.ts src/ | Custom AST transforms |
| JS/TS | ast-grep | sg --pattern 'old($$$)' --rewrite 'new($$$)' | Structural find/replace |
| React | react-codemod | npx codemod@latest react/19/migration-recipe | React version upgrades |
| Next.js | next-codemod | npx @next/codemod@latest | Next.js version upgrades |
| Vue | vue-codemod | npx @vue/codemod src/ | Vue 2 to 3 transforms |
| PHP | Rector | vendor/bin/rector process src | PHP version + framework upgrades |
| Python | pyupgrade | pyupgrade --py314-plus *.py | Python version syntax upgrades |
| Python | django-upgrade | django-upgrade --target-version 5.0 *.py | Django version upgrades |
| Go | gofmt | gofmt -w . | Go formatting updates |
| Go | gofix | go fix ./... | Go API changes |
| Rust | cargo fix | cargo fix --edition | Rust edition migration |
| Multi | ast-grep | sg scan --rule rules.yml | Any language with custom rules |
Migration failed or caused issues — how to roll back?
│
├─ Code-only change, no data migration
│ ├─ Small number of commits
│ │ └─ Git Revert
│ │ git revert --no-commit HEAD~N..HEAD && git commit
│ │ Pros: clean history, safe for shared branches
│ │ Cons: merge conflicts if code has diverged
│ │
│ └─ Entire feature branch
│ └─ Revert merge commit
│ git revert -m 1 <merge-commit-sha>
│
├─ Feature flag controlled
│ └─ Toggle flag off
│ Instant rollback, no deployment needed
│ Keep old code path until new path is proven
│
├─ Database schema changed
│ ├─ Reversible migration exists
│ │ └─ Run down migration
│ │ rails db:rollback / php artisan migrate:rollback / alembic downgrade
│ │
│ └─ Irreversible migration (dropped column, changed type)
│ └─ Restore from backup + replay write-ahead log
│ This is why you take backups BEFORE migration
│
└─ Infrastructure / deployment
├─ Blue-Green deployment
│ └─ Switch traffic back to blue (old) environment
│
├─ Canary deployment
│ └─ Route 100% traffic back to stable version
│
└─ Container orchestration (K8s)
└─ kubectl rollout undo deployment/app
| Gotcha | Why It Happens | Prevention |
|--------|---------------|------------|
| Upgrading multiple major versions at once | Each major version may have sequential breaking changes that compound | Upgrade one major version at a time, verify, then proceed |
| Lock file not committed before migration | Cannot reproduce pre-migration dependency state | Always commit lock files; take a snapshot branch before starting |
| Running codemods without committing first | Cannot diff what the codemod changed vs your manual changes | Commit clean state, run codemod, commit codemod changes separately |
| Ignoring deprecation warnings in current version | Deprecated APIs are removed in next major version | Fix all deprecation warnings BEFORE upgrading |
| Testing only happy paths after migration | Edge cases and error paths are most likely to break | Run full test suite plus manual exploratory testing |
| Not checking transitive dependencies | A direct dep upgrade may pull in incompatible transitive deps | Use npm ls, pip show, cargo tree to inspect dependency tree |
| Assuming codemods catch everything | Codemods handle common patterns, not all patterns | Review codemod output manually; check for skipped files |
| Skipping the migration guide | Framework authors document known pitfalls and workarounds | Read the official migration guide end-to-end before starting |
| Migrating in a long-lived branch | Main branch diverges, causing painful merge conflicts | Use feature flags for incremental migration on main |
| Not updating CI to test both versions | CI passes on old version but new version has failures | Add matrix testing for both versions during transition |
| Database migration without backup | Irreversible schema changes with no recovery path | Always backup before migration; test rollback procedure |
| Forgetting to update Docker/CI base images | Code upgraded but runtime is still old version | Update Dockerfile FROM, CI config, and deployment manifests |
| File | Contents | Lines |
|------|----------|-------|
| references/framework-upgrades.md | React 18→19, Next.js Pages→App Router, Vue 2→3, Laravel 10→13, Angular, Django upgrade paths | ~700 |
| references/language-upgrades.md | Python 3.9→3.14, Node 18→26, TypeScript 4→6, Go 1.20→1.26, Rust 2021→2024, PHP 8.1→8.5 | ~650 |
| references/dependency-management.md | Audit tools, update strategies, lock files, monorepo deps, supply chain security | ~550 |
This skill hardcodes specific framework/language target versions (React 19, Laravel 13, Python 3.14, Node 26, TypeScript 6, Go 1.26, Rust 2024, PHP 8.5). scripts/check-migrate-facts.py guards them against silent drift:
# Structural (PR CI, no network): every catalogued target version still appears
# where it is recorded (description vs body), and the currency note carries a year.
python scripts/check-migrate-facts.py --offline # exit 0 consistent, 10 drift
# Live (freshness job, never blocks a PR): each target is resolved against
# endoflife.date (python/nodejs/laravel/php/go) and npm (react/typescript).
python scripts/check-migrate-facts.py --live # exit 10 a target lags latest, 7 unreachable
The canonical target-version list lives in assets/migrate-facts.json; when you change a recommended target, update it to match or --offline fails CI. A --live drift means the skill is naming an older target than the ecosystem's current stable — review, don't auto-rewrite.
| Skill | When to Combine |
|-------|----------------|
| testing-ops | Ensuring test coverage before migration, writing regression tests after |
| debug-ops | Diagnosing failures introduced by migration, bisecting breaking commits |
| git-ops | Branch strategy for migration, git bisect to find breaking change |
| refactor-ops | Code transformations that often accompany version upgrades |
| ci-cd-ops | Updating CI pipelines to test against new versions, matrix builds |
| container-orchestration | Updating base images, Dockerfile changes for new runtime versions |
| security-ops | Vulnerability remediation that triggers dependency upgrades |
testing
Audit any repo against the agentic-quality doctrine — score entry docs, structure, and enforcement gates, then map each finding to its fix. Triggers on: repo doctor, repo audit, agentic quality, is this repo agent-friendly, doc drift, stale AGENTS.md, monorepo structure, nested CLAUDE.md.
data-ai
Router for parallel or recurring agent work across six skills. Covers: parallel agents, fan out work, delegate to workers, run overnight, scheduled loop, land branches, mixed-model fleet, orchestrate workers, background agents at scale. Triggers on: which skill for parallel work, fan out agents, spawn workers, run this overnight, schedule a loop, land my branches, heterogeneous fleet, delegate to cheaper model, autonomous loop.
tools
Heterogeneous cross-provider fleet - GLM (z.ai), Codex (OpenAI), Grok (xAI), Anthropic Sonnet/Opus/Haiku - from one session, porting the native Workflow tool's patterns (adversarial verify, judge panels, journal resume) to OS-process workers. Triggers: fleetflow, heterogeneous/mixed-model fleet, codex worker, grok worker, cross-provider fan-out, cross-model verify.
development
Application/game-scale three.js: ES modules, GLTF pipeline (DRACO/KTX2/meshopt), AnimationMixer, physics (rapier/cannon-es), react-three-fiber, and performance at scale (InstancedMesh, LOD, draw calls). Triggers on: three.js, GLTFLoader, r3f, game loop, WebGL memory leak, boids.