| name | Refactor |
| description | Safe code refactoring with proper testing and incremental changes |
| triggers | ["/refactor","refactor this","clean up code","restructure"] |
| allowed-tools | ["Read","Write","Edit","Glob","Grep","Bash(npm run test*)","Bash(pnpm test*)","Bash(yarn test*)","Bash(npm run lint*)","Bash(git diff*)","Bash(git status*)"] |
Refactor Skill
Safely restructure code without changing behavior.
Golden Rule
Refactoring changes HOW code works, not WHAT it does.
All tests should pass before AND after refactoring.
Process
1. Ensure Test Coverage
Before refactoring, verify tests exist:
npm run test
npm run test -- --coverage src/module-to-refactor/
If coverage is low, add tests first before refactoring.
2. Make Small, Incremental Changes
Each step should be:
- A single, focused change
- Independently committable
- Passing all tests
Bad: One massive commit that changes everything
Good: Series of small commits, each improving the code
3. Run Tests After Each Change
npm run test -- --watch src/module/
4. Commit Frequently
git commit -m "refactor(auth): extract token validation to separate function"
git commit -m "refactor(auth): rename validateToken to verifyJWT"
git commit -m "refactor(auth): move JWT logic to dedicated service"
Common Refactoring Patterns
Extract Function
When: Code block does one specific thing
function processOrder(order) {
}
function processOrder(order) {
const total = calculateTotal(order);
validateInventory(order.items);
sendOrderNotifications(order);
}
Extract Module/Class
When: Related functions should be grouped
// Before: utils.ts with 50 functions
// After:
// date-utils.ts - date formatting functions
// string-utils.ts - string manipulation
// validation-utils.ts - validators
Rename for Clarity
When: Names don't describe purpose
const d = new Date();
function proc(x) { ... }
const createdAt = new Date();
function processPayment(transaction) { ... }
Replace Conditionals with Polymorphism
When: Switch/if chains based on type
function calculateArea(shape) {
if (shape.type === 'circle') return Math.PI * shape.radius ** 2;
if (shape.type === 'rectangle') return shape.width * shape.height;
}
class Circle {
calculateArea() { return Math.PI * this.radius ** 2; }
}
class Rectangle {
calculateArea() { return this.width * this.height; }
}
Remove Duplication (DRY)
When: Same code appears in multiple places
import { validateEmail } from '@/utils/validation';
Simplify Conditionals
When: Complex boolean logic
if (user && user.subscription && user.subscription.active && !user.banned) {
}
function canAccessPremiumContent(user) {
if (!user) return false;
if (user.banned) return false;
return user.subscription?.active ?? false;
}
if (canAccessPremiumContent(user)) {
}
Refactoring Checklist
Warning Signs to Stop
- Tests start failing unexpectedly
- Scope is growing beyond original plan
- You're tempted to "also fix this bug"
- Changes are getting hard to explain
When in doubt, commit what you have and reassess.
Code Smells to Look For
| Smell | Refactoring |
|---|
| Long function | Extract functions |
| Long parameter list | Introduce parameter object |
| Duplicate code | Extract shared function |
| Large class | Split into focused classes |
| Feature envy | Move method to appropriate class |
| Primitive obsession | Create domain types |
| Deep nesting | Extract functions, early returns |