Large Refactors
Large Refactors with ralph
Section titled “Large Refactors with ralph”Refactoring is where ralph shines. The repetitive, systematic nature of large refactors is perfectly suited for iterative AI loops.
Why ralph Excels at Refactoring
Section titled “Why ralph Excels at Refactoring”- Systematic progress — Each iteration tackles more of the same task
- Pattern consistency — The AI sees its own patterns and continues them
- Error recovery — If something breaks, the next iteration can fix it
- No context fatigue — Fresh context each iteration, consistent quality
Example: Rename Across Codebase
Section titled “Example: Rename Across Codebase”Rename UserService to AccountService everywhere.
ralph initEdit .ralph/config.toml:
adapter = "claude"maxIterations = 20Prompt (.plans/PROMPT.md)
Section titled “Prompt (.plans/PROMPT.md)”# Refactor: Rename UserService to AccountService
Rename all occurrences of `UserService` to `AccountService` across the codebase.
## Scope- File names: `UserService.ts` → `AccountService.ts`- Class names: `class UserService` → `class AccountService`- Imports: `import { UserService }` → `import { AccountService }`- Type references: `UserService` → `AccountService`- Variable names: `userService` → `accountService`
## Process1. Run `grep -r "UserService" src/` to find remaining occurrences2. Update one file at a time3. Run `npm run typecheck` after each change4. Commit after each file
## Verification- `npm run typecheck` passes- `npm test` passes- `grep -r "UserService" src/` returns nothing
## ProgressTrack completed files in progress.txt
## CompletionWhen `grep -r "UserService" src/` returns no results, output:<promise>COMPLETE</promise>Example: API Migration
Section titled “Example: API Migration”Migrate from deprecated API v1 to v2.
Prompt
Section titled “Prompt”# Migrate API v1 to v2
All API calls using `/api/v1/` need to migrate to `/api/v2/`.
## Migration Rules
| v1 Endpoint | v2 Endpoint | Changes ||-------------|-------------|---------|| `/api/v1/users` | `/api/v2/accounts` | Name change || `/api/v1/items` | `/api/v2/products` | Name + response shape || `/api/v1/orders` | `/api/v2/orders` | New auth header |
## Response Shape Changes
v1 `items` response:```json{ "items": [...], "total": 100 }v2 products response:
{ "data": [...], "meta": { "total": 100 } }Process
Section titled “Process”- Find files with
grep -r "api/v1" src/ - Update one endpoint at a time
- Update response handling if needed
- Test with
npm test - Commit
Completion
Section titled “Completion”When no references to /api/v1/ remain and all tests pass, output:
## Example: Framework Upgrade
Upgrade from React 17 to React 18.
### Prompt
```markdown# Upgrade React 17 to React 18
Migrate the codebase from React 17 patterns to React 18.
## Required Changes
### 1. Root APIChange:```jsximport ReactDOM from 'react-dom';ReactDOM.render(<App />, document.getElementById('root'));To:
import { createRoot } from 'react-dom/client';const root = createRoot(document.getElementById('root'));root.render(<App />);2. TypeScript Types
Section titled “2. TypeScript Types”Update any React.FC that relies on implicit children prop.
Process
Section titled “Process”- Start with entry point (src/index.tsx)
- Check for warnings with
npm run build - Fix TypeScript errors with
npm run typecheck - Run tests to verify behavior
Verification
Section titled “Verification”npm run buildsucceedsnpm testpasses
Completion
Section titled “Completion”When build succeeds and all tests pass, output:
## Example: Dependency Replacement
Replace Moment.js with date-fns.
### Prompt
```markdown# Replace Moment.js with date-fns
Migrate all date handling from Moment.js to date-fns.
## Common Conversions
| Moment | date-fns ||--------|----------|| `moment()` | `new Date()` || `moment(date).format('YYYY-MM-DD')` | `format(date, 'yyyy-MM-dd')` || `moment(date).add(1, 'days')` | `addDays(date, 1)` || `moment(date).diff(other, 'days')` | `differenceInDays(date, other)` || `moment(date).isAfter(other)` | `isAfter(date, other)` || `moment(date).startOf('day')` | `startOfDay(date)` |
## Import Pattern```typescriptimport { format, addDays, isAfter } from 'date-fns';Process
Section titled “Process”- Find Moment imports:
grep -r "from 'moment'" src/ - Migrate one file at a time
- Run tests after each file
- Remove Moment import when file is done
Final Step
Section titled “Final Step”When all files are migrated, run:
npm uninstall momentCompletion
Section titled “Completion”When no imports from ‘moment’ remain and all tests pass, output:
## Tips for Refactoring Tasks
### 1. Provide Clear Conversion Rules
The AI needs to know exactly how to transform code. Tables work well:
```markdown| Before | After ||--------|-------|| `oldPattern()` | `newPattern()` |2. Include Verification Commands
Section titled “2. Include Verification Commands”Always give the AI a way to check its work:
## Verify Each ChangeRun `npm run typecheck && npm test` after each file.3. Scope Appropriately
Section titled “3. Scope Appropriately”Too broad = AI gets confused. Too narrow = too many iterations.
## ScopeOnly modify files in src/services/.Ignore test files (they'll be updated separately).4. Handle Edge Cases
Section titled “4. Handle Edge Cases”Document known edge cases:
## Edge Cases- Nested callbacks: Extract to named functions first- Dynamic imports: May need manual review- Generated files: Skip files in src/generated/5. Track Progress
Section titled “5. Track Progress”## Progress TrackingAfter completing each directory, update progress.txtCommit with message: "refactor(dirname): migrate to new API"