## Migration Framework
### Phase 1: Migration Assessment
```
I need to migrate the following codebase:
**Current State:**
- Framework/Language: [Current tech]
- Version: [Current version]
- Codebase Size: [LOC, number of files]
- Key Dependencies: [List major deps]
- Architecture: [Monolith, microservices, etc.]
**Target State:**
- Framework/Language: [Target tech]
- Version: [Target version]
- Motivation: [Why migrate? Performance, maintainability, EOL support]
**Constraints:**
- Timeline: [Deadline if any]
- Testing: [Test coverage, testing strategy]
- Deployment: [Can we do incremental rollout or must be big bang?]
Perform a migration assessment:
1. **Breaking Changes Analysis**
- List all breaking changes between current and target versions
- Identify affected code patterns in our codebase
- Estimate impact (% of codebase affected)
2. **Dependency Compatibility**
- Check if all our dependencies support target version
- Identify deprecated dependencies needing replacement
- Flag dependencies with no migration path
3. **Risk Assessment**
- High-risk areas (complex logic, limited test coverage)
- Areas where automated migration is safe
- Areas requiring manual review
4. **Migration Strategy**
- Recommend incremental vs. big-bang approach
- Suggest migration order (least to most complex)
- Identify codemods or automated tools available
5. **Effort Estimate**
- Estimated person-hours by phase
- Recommended team size and skill level
```
### Phase 2: Automated Migration
#### Codemod Generation
````
Generate a codemod to automatically migrate:
**Pattern to Replace:**
[Old code pattern]
**New Pattern:**
[New code pattern]
**Context:**
- Language: [JavaScript, TypeScript, Python, etc.]
- Tool: [jscodeshift, ast-grep, libcst, etc.]
**Requirements:**
1. Handle edge cases: [List known variations]
2. Preserve comments and formatting
3. Skip patterns in test files (or handle differently)
4. Add TODO comments for manual review if uncertain
Provide:
- Complete codemod script with comments
- Test cases demonstrating before/after
- Dry-run command to preview changes
- Execution instructions
**Example:**
```javascript
// Migrate from React class components to functional components with hooks
// Before:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
console.log('mounted');
}
render() {
return <div>{this.state.count}</div>;
}
}
// After:
function MyComponent(props) {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('mounted');
}, []);
return <div>{count}</div>;
}
````
```
#### Incremental Migration Strategy
```
Design an incremental migration plan for:
**Codebase:** [Description]
**Migration:** [From X to Y]
Create a phased migration plan:
**Phase 1: Foundation (Week 1-2)**
- Set up dual-mode build system (support both old and new)
- Migrate build configuration and tooling
- Update CI/CD pipeline
- Establish feature flags for gradual rollout
**Phase 2: Low-Risk Modules (Week 3-5)**
- Identify self-contained, well-tested modules
- Migrate utility functions and helpers first
- Update tests to pass with new framework
- Deploy to staging, monitor for issues
**Phase 3: Core Features (Week 6-10)**
- Migrate user-facing features one by one
- Use feature flags to toggle between old/new
- A/B test in production (10% → 50% → 100%)
- Gather performance and error metrics
**Phase 4: Complex Components (Week 11-14)**
- Migrate high-risk, complex modules
- Allocate extra time for manual testing
- Plan rollback strategy for each deployment
**Phase 5: Cleanup (Week 15-16)**
- Remove old framework code and dependencies
- Delete feature flags and dual-mode infrastructure
- Update documentation
- Performance tuning and optimization
For each phase, provide:
- Specific files/modules to migrate
- Automated vs. manual migration approach
- Test strategy and acceptance criteria
- Rollback plan if issues arise
```
### Phase 3: Dependency Updates
#### Breaking Change Resolution
```
I'm upgrading [dependency] from v[X] to v[Y] and encountering breaking changes:
**Breaking Changes:**
[List breaking changes from changelog]
**Our Usage:**
[Show how we currently use this dependency]
For each breaking change:
1. **Impact Analysis**
- Which files in our codebase are affected?
- How critical is this functionality?
2. **Migration Path**
- Show exact code changes needed
- Provide before/after examples
- Explain why the new approach is better
3. **Alternative Solutions**
- If migration is too complex, suggest workarounds
- Consider polyfills or adapter layers
- Evaluate staying on old version temporarily
4. **Testing Strategy**
- What tests need updating?
- What new tests should we add?
- How to verify behavior is preserved?
Generate a pull request checklist for this upgrade.
```
#### Dependency Deprecation Replacement
```
I need to replace deprecated dependency:
**Current Dependency:** [Name, version, why it's deprecated]
**Functionality We Use:** [List features we depend on]
**Constraints:** [API compatibility, performance requirements]
Research and recommend replacements:
**Option 1: [Alternative Package]**
- Pros: [Benefits]
- Cons: [Trade-offs]
- Migration Effort: [Low/Medium/High]
- Code Example: [How to use it]
**Option 2: [Another Alternative]**
- Pros:
- Cons:
- Migration Effort:
- Code Example:
**Option 3: Build In-House**
- Pros:
- Cons:
- Implementation Plan:
**Recommendation:** [Which option and why]
Provide migration guide:
1. Install new dependency
2. Update import statements
3. Refactor usage patterns
4. Update tests
5. Remove old dependency
```
### Phase 4: Type Safety Migration
#### JavaScript to TypeScript
```
Migrate this JavaScript codebase to TypeScript:
**Codebase Structure:**
[Describe folder structure, key files]
**Current JavaScript Code:**
[Paste representative files]
**Migration Strategy:**
1. **Project Setup**
- tsconfig.json configuration
- Update build scripts (webpack, vite, etc.)
- Add TypeScript dependencies
2. **Incremental Adoption**
- Rename .js → .ts gradually
- Allow `any` initially, tighten later
- Start with leaf nodes (no dependencies)
- Work up the dependency tree
3. **Type Definitions**
- Generate .d.ts for third-party libs if missing
- Define interfaces for data models
- Add types for function signatures
- Type React props and state
4. **Refactoring Opportunities**
- Replace `PropTypes` with TypeScript interfaces
- Convert string enums to TypeScript enums
- Use strict null checks to catch bugs
- Leverage discriminated unions for polymorphism
For each file:
- Show TypeScript equivalent
- Explain type decisions
- Highlight bugs caught by TypeScript
- Recommend linter rules (strict mode, no-explicit-any)
Provide automated migration script where possible.
```
### Phase 5: Testing & Validation
#### Behavioral Equivalence Testing
```
Verify that migrated code behaves identically to original:
**Original Code:** [Old implementation]
**Migrated Code:** [New implementation]
Create test suite to validate equivalence:
1. **Unit Tests**
- Test all function inputs/outputs match
- Include edge cases (null, undefined, empty arrays)
- Test error handling and exceptions
2. **Integration Tests**
- Test interactions between migrated and unmigrated code
- Verify API contracts are maintained
- Test database queries return same results
3. **Snapshot/Golden Testing**
- Capture outputs from old code
- Run new code with same inputs
- Diff outputs to detect regressions
4. **Performance Benchmarks**
- Compare execution time
- Memory usage comparison
- Identify performance improvements or regressions
5. **Chaos/Fuzz Testing**
- Generate random inputs
- Ensure both versions handle gracefully
- Catch edge cases missed in manual testing
Generate test code for each category.
```
#### Migration Smoke Tests
```
Create a smoke test suite to run after each migration phase:
**Critical User Flows:**
1. [Flow 1: e.g., User login]
2. [Flow 2: e.g., Create new item]
3. [Flow 3: e.g., Checkout process]
For each flow:
- E2E test script (Playwright, Cypress)
- Expected behavior and assertions
- Performance budget (load time < X ms)
- Accessibility checks
**Automated Checks:**
- No console errors in browser
- All API calls succeed (no 500s)
- CSS renders correctly (visual regression)
- No memory leaks (heap snapshots)
**Manual Checklist:**
- [ ] Test on Chrome, Firefox, Safari
- [ ] Test on mobile devices
- [ ] Test with slow network (3G simulation)
- [ ] Test with screen reader
- [ ] Test with different user roles/permissions
Provide test scripts and monitoring dashboard.
```
## Advanced Techniques
### Large-Scale AST Transformations
```
For complex migrations requiring AST manipulation:
**Tool Choice:**
- JavaScript/TypeScript: jscodeshift, ts-morph
- Python: libcst, rope
- Java: OpenRewrite, Refaster
- Go: gorename, gomvpkg
**Transformation Pattern:**
1. Parse code into AST
2. Traverse AST to find target nodes
3. Transform or replace nodes
4. Regenerate code from modified AST
**Example: Rename all class methods matching pattern**
```javascript
export default function transformer(file, api) {
const j = api.jscodeshift;
return j(file.source)
.find(j.MethodDefinition, {
key: { name: (name) => name.startsWith('UNSAFE_') }
})
.forEach((path) => {
path.value.key.name = path.value.key.name.replace('UNSAFE_', '');
})
.toSource();
}
```
Provide AST transformation code for your specific migration.
```
### Gradual Typing with Bridge Layers
```
When migrating with breaking API changes, use adapter/bridge pattern:
**Old API:**
```javascript
legacyApi.getData(callback);
```
**New API:**
```javascript
await modernApi.fetchData();
```
**Bridge Layer:**
```javascript
// Adapter that makes old code work with new API
class LegacyAdapter {
getData(callback) {
modernApi
.fetchData()
.then((data) => callback(null, data))
.catch((err) => callback(err));
}
}
const legacyApi = new LegacyAdapter();
// Now old code works without changes!
```
This allows incremental migration:
1. Replace backend with new API
2. Old consumers use adapter
3. Gradually update consumers to use new API directly
4. Remove adapter once migration complete
Generate adapter code for your migration scenario.
````
## Best Practices
1. **Comprehensive Testing First**: Increase test coverage before migration
2. **Version Control Discipline**: Commit frequently, use feature branches
3. **Documentation**: Update docs alongside code migration
4. **Performance Benchmarks**: Establish baseline before migration
5. **Rollback Plan**: Know how to revert at each phase
6. **Team Communication**: Keep stakeholders informed of progress and risks
7. **Automate Where Possible**: Use codemods to reduce manual work
8. **Incremental Deployment**: Gradual rollout with feature flags
## Example Session
**User**: "I need to migrate our React app from class components to functional components with hooks."
**Opus Response**:
> I'll create a comprehensive migration plan:
>
> **Phase 1: Assessment**
> ```bash
> # Find all class components
> grep -r "class.*extends.*Component" src/ | wc -l
> # Result: 47 class components
> ```
>
> **Migration Priority:**
> 1. **Low-Risk (15 components)**: Pure components with no lifecycle methods
> 2. **Medium-Risk (22 components)**: Components with componentDidMount, componentDidUpdate
> 3. **High-Risk (10 components)**: Complex lifecycle, refs, error boundaries
>
> **Automated Codemod:**
> I'll use `react-codemod` with custom transformations:
> ```bash
> npx react-codemod class-to-function src/
> ```
>
> **Manual Migration Template:**
> ```javascript
> // Before:
> class UserProfile extends React.Component {
> state = { loading: true };
>
> componentDidMount() {
> fetchUser(this.props.id).then(user =>
> this.setState({ user, loading: false })
> );
> }
>
> componentDidUpdate(prevProps) {
> if (prevProps.id !== this.props.id) {
> this.setState({ loading: true });
> fetchUser(this.props.id).then(user =>
> this.setState({ user, loading: false })
> );
> }
> }
>
> render() {
> return this.state.loading ? <Spinner /> : <Profile user={this.state.user} />;
> }
> }
>
> // After:
> function UserProfile({ id }) {
> const [user, setUser] = useState(null);
> const [loading, setLoading] = useState(true);
>
> useEffect(() => {
> setLoading(true);
> fetchUser(id).then(user => {
> setUser(user);
> setLoading(false);
> });
> }, [id]); // Re-run when id changes
>
> return loading ? <Spinner /> : <Profile user={user} />;
> }
> ```
>
> Shall I generate the full codemod script and testing plan?
## Related Resources
- [jscodeshift](https://github.com/facebook/jscodeshift) for JavaScript codemods
- [ts-morph](https://ts-morph.com/) for TypeScript AST manipulation
- [OpenRewrite](https://docs.openrewrite.org/) for Java refactoring
- [libcst](https://libcst.readthedocs.io/) for Python AST transformations
````