Dependency Migration
Replace one library with another, or migrate deprecated API patterns within the same library.
Quick Start
Replace moment.js with date-fns
Migrate from webpack to vite
Remove deprecated forwardRef usage (React 19)
Switch from lodash to es-toolkit
Migrate Vue Options API to Composition API
Scope
| Type |
Example |
Trigger |
| Library replacement |
moment.js → date-fns |
"replace X with Y" |
| API pattern migration |
React 19 forwardRef removal |
"remove deprecated X", "migrate to new Y API" |
Both types follow the same test-first workflow below.
Workflow
Non-linear execution: Phases are numbered for reference, not strict order. If findings in any phase invalidate earlier assumptions, restart from the affected phase.
Phase 1: Environment Analysis
- Detect package manager from lockfile (see package-managers.md)
- Detect monorepo structure
- Detect CI, hooks, changeset config (see repo-conventions.md)
- Detect test infrastructure (test runner, tsconfig.json, linter)
Phase 2: Identify Migration Target
For library replacement:
- Parse source library (to remove) and target library (to add)
- Detect current usage scope: grep for imports/requires of source library
- Count affected files and usage patterns
For API pattern migration:
- Identify deprecated/removed API pattern
- Scan all occurrences in codebase
- Identify the replacement pattern from docs
Phase 3: Documentation & Compatibility Analysis
Consult all sources (use subagents for parallel lookup when possible; see context7-integration.md):
- Context7 → Query both libraries for API comparison, migration guides
- Community resources → Search for known migration guides
- Code analysis → Map source API usage to target equivalents
Conflict resolution: If sources disagree on API equivalence or behavior, use the most conservative conclusion and flag the discrepancy.
Build an API mapping table:
| Source |
Target |
Notes |
moment().format('YYYY') |
format(date, 'yyyy') |
Different format tokens |
React.forwardRef((props, ref) => ...) |
function Component({ ref, ...props }) |
ref is now a regular prop |
See migration-patterns.md for methodology and common patterns.
Phase 3.5: Official Tools & Compat Layer Detection
Check for official/community migration tools before writing custom migrations:
For library replacement:
- Compat layer — e.g.,
es-toolkit/compat for lodash
- Ask user: "Use compat for gradual migration, or full replacement?"
- Compat-first: swap import paths → verify → optionally migrate to native API later
- Codemods — e.g.,
jscodeshift transforms from library authors
For API pattern migration:
- Official codemods — e.g.,
npx react-codemod rename-unsafe-lifecycles
- Framework CLI migration — e.g.,
npx @angular/cli update, npx storybook automigrate
Decision flow:
- Codemod exists → run codemod first, handle remaining manually
- Compat layer available → ask user preference (gradual vs full)
- Neither → proceed to Phase 4
Phase 3.7: Related Package Detection
For library replacement:
- Check if
@types/<source> exists → should be removed (scoped: @scope/pkg → @types/scope__pkg)
- Check if target requires
@types/<target> or companion packages
- For each related package found, also check for its
@types/ counterpart (e.g., react-dom → @types/react-dom)
- Check for related plugins/adapters referencing the source library
For API pattern migration:
- Usually no related packages needed, but check for community wrappers
Present findings and ask user whether to include.
Phase 4: Test-First Verification
Validate the migration approach before batch execution.
- Scan all usage — comprehensive grep for all patterns to migrate
- Write test diffs in /tmp — pick representative examples (not all files):
- Select 2-3 diverse usage patterns (simple, complex, edge case). If more than 10 distinct patterns exist, sample at least 30% and reflect actual coverage in the confidence index
- Create migrated versions in /tmp
- Run type check + tests against migrated snippets
/tmp/deps-shift-verify-<package>-<timestamp>/
├── package.json # Minimal deps (target package only)
├── tsconfig.json # Copied from project, paths/aliases adjusted for /tmp
├── original/ # Copy of affected code snippets
├── migrated/ # Proposed migration applied
└── test-runner.sh # Must run tsc --noEmit at minimum, must NOT be just exit 0
Environment setup: Create a minimal package.json, install only the target package version fresh. Copy project's tsconfig.json; remove paths, baseUrl, and references fields that point to project-specific locations — /tmp resolves modules through its own node_modules only. Never mutate the project's actual node_modules.
- Verify approach works before committing to full migration
- Pass → proceed to Phase 5
- Fail → iterate (max 3 attempts), then present failure analysis
Fallback: When tests can't be written → subagent 3-pass review loop:
- Pass 1 (Direct): correctness of API mapping, import resolution
- Pass 2 (Best Practice): idiomatic target library usage
- Pass 3 (Critical Think): edge cases, behavioral differences, risks
- Fix + loop until all passes clean
Phase 5: Migration Plan & Confidence Index
Present structured plan with confidence index:
- File-by-file change summary
- API mapping table (validated by Phase 4)
- Potential issues / no direct equivalent
- Confidence index with factor breakdown and boost options
- Repo convention actions
Always get user confirmation before executing.
Phase 6: Execute Migration
- Install target library (if library replacement)
- Apply transformations file by file using validated mapping
- Checkpoint: Verify all files have been transformed — grep for remaining source library imports. If any remain, do NOT proceed to removal
- Check for peer dependency conflicts — present options if found
- Clean up unused imports/types
- Clean up /tmp verification files
Note: Source library removal happens in Phase 8 after final verification passes. Do NOT remove it here — keeping it installed during verification ensures rollback is possible if issues are found.
Phase 7: Repo Convention Compliance
Detect and follow project conventions (see repo-conventions.md):
- Changesets → create changeset file
- Conventional commits → follow format
- CI checks → run matching local commands
- Pre-commit hooks → ensure hooks pass
- Custom scripts → run test, lint, typecheck
Phase 8: Final Verification
- Type check → 2. Lint → 3. Test suite → 4. Build
- For complex migrations: run subagent Pass 3 (Critical Think) as final quality gate
- After all checks pass: Remove source library from
package.json (if library replacement). If source is a transitive dep of other packages, it stays in lockfile — only remove the direct dependency
- Run install to update lockfile after removal
- All pass → report success
- Failures → analyze if migration-related, attempt fix, present remaining to user (source library is still installed, so rollback is straightforward)
Guidelines
DO
- Build a complete API mapping table — map every source API to target equivalent before migrating
- Check for official codemods first — search npm registry and migration guides before writing custom transforms
- Offer compat layers when available — ask user preference (gradual vs full), never assume
- Test migration approach in /tmp first — validate on representative samples before batch
- Use Context7 for both libraries — query source and target library docs in parallel
- Handle "no equivalent" cases — ask user, implement custom wrapper, or document manual step
- Always confirm before execution — present migration plan, get user approval
- Follow repo conventions — detect and comply with changesets, commit format, CI checks
DON'T
- Skip codemod detection — always check for official tools first
- Skip test-first verification — never execute batch migration without validating approach
- Remove source library prematurely — verify all usage migrated before removing
- Assume API equivalence — subtle behavioral differences exist (async vs sync, shallow vs deep copy)
- Force migration when tests fail — present failure analysis, let user decide
- Assume compat layer preference — always ask user (gradual vs clean break)
- Migrate test files last — migrate tests alongside implementation to catch issues early
Error Handling
| Error |
Action |
| No direct API equivalent found |
Document gap, ask user for custom wrapper or alternative approach |
| Codemod crashes partway |
Report progress, show transformed files, suggest manual completion |
| Context7 MCP tool not found |
Suggest installation, continue with community guides + code analysis |
| Type errors after migration |
Analyze if source/target type mismatch, suggest type assertion or wrapper |
| Behavioral difference detected |
Flag to user with before/after examples, get approval |
| Tests still fail after 3 iterations |
Present failure analysis, ask user how to proceed |
| /tmp write fails |
Fall back to subagent review |
Reference Files
- package-managers.md — Detection matrix and commands
- repo-conventions.md — Convention detection and compliance
- confidence-index.md — Confidence index specification
- context7-integration.md — Context7 MCP detection and usage
- migration-patterns.md — Methodology and common patterns
Notes
- Requirements:
gh CLI (for releases API), package manager CLI
- Context7: Optional but recommended; install through the current agent's plugin or MCP setup flow.
- Supported ecosystems: npm, pnpm, yarn, bun, cargo, pip/uv/poetry, go, bundler, composer
- Limitations: Private registry auth requires manual setup; no auto-handling of 2FA prompts
- Monorepos: Detected automatically, but user may need to specify target package for large workspaces
- Boundary: Use this skill when replacing one library with another or migrating API patterns. For version bumps (A v1 → A v2), use
deps-upgrade instead.
1---2name: deps-migrate3description: Replace one library with another (e.g., moment.js to date-fns, webpack to vite), or migrate deprecated API patterns within the same library (e.g., React 19 forwardRef removal, Vue 3 Options API to Composition API). Use when asked to "replace X with Y", "migrate from X to Y", "switch from X to Y", "swap X for Y", "convert from X to Y", "port from X to Y", "remove deprecated forwardRef", "migrate to new API", or when planning library replacement or API migration. Also trigger when the user mentions switching libraries, finding alternatives, or removing deprecated patterns. Boundary: for replacing libraries or migrating API patterns. Use deps-upgrade for version bumps within the same library.4---56# Dependency Migration78Replace one library with another, or migrate deprecated API patterns within the same library.910## Quick Start1112> Replace moment.js with date-fns1314> Migrate from webpack to vite1516> Remove deprecated forwardRef usage (React 19)1718> Switch from lodash to es-toolkit1920> Migrate Vue Options API to Composition API2122## Scope2324| Type | Example | Trigger |25|------|---------|---------|26| **Library replacement** | moment.js → date-fns | "replace X with Y" |27| **API pattern migration** | React 19 forwardRef removal | "remove deprecated X", "migrate to new Y API" |2829Both types follow the same test-first workflow below.3031## Workflow3233> **Non-linear execution**: Phases are numbered for reference, not strict order. If findings in any phase invalidate earlier assumptions, restart from the affected phase.3435### Phase 1: Environment Analysis3637- Detect package manager from lockfile (see [package-managers.md](references/package-managers.md))38- Detect monorepo structure39- Detect CI, hooks, changeset config (see [repo-conventions.md](references/repo-conventions.md))40- Detect test infrastructure (test runner, tsconfig.json, linter)4142### Phase 2: Identify Migration Target4344**For library replacement:**45- Parse source library (to remove) and target library (to add)46- Detect current usage scope: grep for imports/requires of source library47- Count affected files and usage patterns4849**For API pattern migration:**50- Identify deprecated/removed API pattern51- Scan all occurrences in codebase52- Identify the replacement pattern from docs5354### Phase 3: Documentation & Compatibility Analysis5556Consult all sources (use subagents for parallel lookup when possible; see [context7-integration.md](references/context7-integration.md)):571. **Context7** → Query both libraries for API comparison, migration guides582. **Community resources** → Search for known migration guides593. **Code analysis** → Map source API usage to target equivalents6061**Conflict resolution**: If sources disagree on API equivalence or behavior, use the most conservative conclusion and flag the discrepancy.6263Build an API mapping table:6465| Source | Target | Notes |66|--------|--------|-------|67| `moment().format('YYYY')` | `format(date, 'yyyy')` | Different format tokens |68| `React.forwardRef((props, ref) => ...)` | `function Component({ ref, ...props })` | ref is now a regular prop |6970See [migration-patterns.md](references/migration-patterns.md) for methodology and common patterns.7172### Phase 3.5: Official Tools & Compat Layer Detection7374Check for official/community migration tools **before** writing custom migrations:7576**For library replacement:**77- **Compat layer** — e.g., `es-toolkit/compat` for lodash78 - Ask user: "Use compat for gradual migration, or full replacement?"79 - Compat-first: swap import paths → verify → optionally migrate to native API later80- **Codemods** — e.g., `jscodeshift` transforms from library authors8182**For API pattern migration:**83- **Official codemods** — e.g., `npx react-codemod rename-unsafe-lifecycles`84- **Framework CLI migration** — e.g., `npx @angular/cli update`, `npx storybook automigrate`8586Decision flow:87- **Codemod exists** → run codemod first, handle remaining manually88- **Compat layer available** → ask user preference (gradual vs full)89- **Neither** → proceed to Phase 49091### Phase 3.7: Related Package Detection9293**For library replacement:**94- Check if `@types/<source>` exists → should be removed (scoped: `@scope/pkg` → `@types/scope__pkg`)95- Check if target requires `@types/<target>` or companion packages96- For each related package found, also check for its `@types/` counterpart (e.g., react-dom → @types/react-dom)97- Check for related plugins/adapters referencing the source library9899**For API pattern migration:**100- Usually no related packages needed, but check for community wrappers101102Present findings and ask user whether to include.103104### Phase 4: Test-First Verification105106Validate the migration approach **before** batch execution.1071081. **Scan all usage** — comprehensive grep for all patterns to migrate1092. **Write test diffs in /tmp** — pick representative examples (not all files):110 - Select 2-3 diverse usage patterns (simple, complex, edge case). If more than 10 distinct patterns exist, sample at least 30% and reflect actual coverage in the confidence index111 - Create migrated versions in /tmp112 - Run type check + tests against migrated snippets113 ```114 /tmp/deps-shift-verify-<package>-<timestamp>/115 ├── package.json # Minimal deps (target package only)116 ├── tsconfig.json # Copied from project, paths/aliases adjusted for /tmp117 ├── original/ # Copy of affected code snippets118 ├── migrated/ # Proposed migration applied119 └── test-runner.sh # Must run tsc --noEmit at minimum, must NOT be just exit 0120 ```121 **Environment setup**: Create a minimal `package.json`, install only the target package version fresh. Copy project's `tsconfig.json`; remove `paths`, `baseUrl`, and `references` fields that point to project-specific locations — /tmp resolves modules through its own `node_modules` only. Never mutate the project's actual `node_modules`.1223. **Verify approach works** before committing to full migration1234. **Pass** → proceed to Phase 51245. **Fail** → iterate (max 3 attempts), then present failure analysis125126**Fallback**: When tests can't be written → subagent 3-pass review loop:127- Pass 1 (Direct): correctness of API mapping, import resolution128- Pass 2 (Best Practice): idiomatic target library usage129- Pass 3 (Critical Think): edge cases, behavioral differences, risks130- Fix + loop until all passes clean131132### Phase 5: Migration Plan & Confidence Index133134Present structured plan with [confidence index](references/confidence-index.md):135- File-by-file change summary136- API mapping table (validated by Phase 4)137- Potential issues / no direct equivalent138- Confidence index with factor breakdown and boost options139- Repo convention actions140141**Always get user confirmation before executing.**142143### Phase 6: Execute Migration1441451. Install target library (if library replacement)1462. Apply transformations file by file using validated mapping1473. **Checkpoint**: Verify all files have been transformed — grep for remaining source library imports. If any remain, do NOT proceed to removal1484. **Check for peer dependency conflicts** — present options if found1495. Clean up unused imports/types1506. Clean up /tmp verification files151152**Note**: Source library removal happens in Phase 8 **after** final verification passes. Do NOT remove it here — keeping it installed during verification ensures rollback is possible if issues are found.153154### Phase 7: Repo Convention Compliance155156Detect and follow project conventions (see [repo-conventions.md](references/repo-conventions.md)):157- Changesets → create changeset file158- Conventional commits → follow format159- CI checks → run matching local commands160- Pre-commit hooks → ensure hooks pass161- Custom scripts → run test, lint, typecheck162163### Phase 8: Final Verification1641651. Type check → 2. Lint → 3. Test suite → 4. Build1665. For complex migrations: run subagent Pass 3 (Critical Think) as final quality gate1676. **After all checks pass**: Remove source library from `package.json` (if library replacement). If source is a transitive dep of other packages, it stays in lockfile — only remove the direct dependency1687. Run install to update lockfile after removal169- All pass → report success170- Failures → analyze if migration-related, attempt fix, present remaining to user (source library is still installed, so rollback is straightforward)171172## Guidelines173174### DO175176- **Build a complete API mapping table** — map every source API to target equivalent before migrating177- **Check for official codemods first** — search npm registry and migration guides before writing custom transforms178- **Offer compat layers when available** — ask user preference (gradual vs full), never assume179- **Test migration approach in /tmp first** — validate on representative samples before batch180- **Use Context7 for both libraries** — query source and target library docs in parallel181- **Handle "no equivalent" cases** — ask user, implement custom wrapper, or document manual step182- **Always confirm before execution** — present migration plan, get user approval183- **Follow repo conventions** — detect and comply with changesets, commit format, CI checks184185### DON'T186187- **Skip codemod detection** — always check for official tools first188- **Skip test-first verification** — never execute batch migration without validating approach189- **Remove source library prematurely** — verify all usage migrated before removing190- **Assume API equivalence** — subtle behavioral differences exist (async vs sync, shallow vs deep copy)191- **Force migration when tests fail** — present failure analysis, let user decide192- **Assume compat layer preference** — always ask user (gradual vs clean break)193- **Migrate test files last** — migrate tests alongside implementation to catch issues early194195## Error Handling196197| Error | Action |198|-------|--------|199| No direct API equivalent found | Document gap, ask user for custom wrapper or alternative approach |200| Codemod crashes partway | Report progress, show transformed files, suggest manual completion |201| Context7 MCP tool not found | Suggest installation, continue with community guides + code analysis |202| Type errors after migration | Analyze if source/target type mismatch, suggest type assertion or wrapper |203| Behavioral difference detected | Flag to user with before/after examples, get approval |204| Tests still fail after 3 iterations | Present failure analysis, ask user how to proceed |205| /tmp write fails | Fall back to subagent review |206207## Reference Files208209- [package-managers.md](references/package-managers.md) — Detection matrix and commands210- [repo-conventions.md](references/repo-conventions.md) — Convention detection and compliance211- [confidence-index.md](references/confidence-index.md) — Confidence index specification212- [context7-integration.md](references/context7-integration.md) — Context7 MCP detection and usage213- [migration-patterns.md](references/migration-patterns.md) — Methodology and common patterns214215## Notes216217- **Requirements**: `gh` CLI (for releases API), package manager CLI218- **Context7**: Optional but recommended; install through the current agent's plugin or MCP setup flow.219- **Supported ecosystems**: npm, pnpm, yarn, bun, cargo, pip/uv/poetry, go, bundler, composer220- **Limitations**: Private registry auth requires manual setup; no auto-handling of 2FA prompts221- **Monorepos**: Detected automatically, but user may need to specify target package for large workspaces222- **Boundary**: Use this skill when replacing one library with another or migrating API patterns. For version bumps (A v1 → A v2), use `deps-upgrade` instead.