Use when restructuring code to improve quality without changing external behavior. Emphasizes safety through tests and incremental changes.
View on GitHubSelect agents to install to:
npx add-skill https://github.com/TheBushidoCollective/han/blob/main/core/skills/refactoring/SKILL.md -a claude-code --skill refactoringInstallation paths:
.claude/skills/refactoring/# Refactoring Skill
Improve code structure and quality while preserving behavior.
## Core Principle
**Tests are your safety net.** Never refactor without tests.
## The Refactoring Cycle
1. **Ensure tests exist and pass**
2. **Make ONE small change**
3. **Run tests** (must still pass)
4. **Commit** (keep changes isolated)
5. **Repeat**
**Each step must be reversible.** If tests fail, revert and try smaller change.
## Pre-Refactoring Checklist
**STOP if any of these are false:**
- [ ] Tests exist for code being refactored
- [ ] All tests currently pass
- [ ] Understand what code does
- [ ] External behavior will remain unchanged
- [ ] Have time to do this properly (not rushing)
**If no tests exist:**
1. Add tests first
2. Verify tests pass
3. THEN refactor
## When to Refactor
### Code Smells That Suggest Refactoring
**Readability issues:**
- Long functions (> 50 lines)
- Deep nesting (> 3 levels)
- Unclear naming
- Magic numbers
- Complex conditionals
**Maintainability issues:**
- Duplication (same code in multiple places)
- God classes (too many responsibilities)
- Feature envy (method uses another class more than its own)
- Data clumps (same groups of parameters passed around)
**Complexity issues:**
- Cyclomatic complexity > 10
- Too many dependencies
- Tightly coupled code
- Difficult to test
### When NOT to Refactor
- **No tests exist** (add tests first)
- **Under deadline pressure** (defer to later)
- **Code works and is readable** (don't over-engineer)
- **Changing external behavior** (that's not refactoring, that's a feature/fix)
- **Right before release** (too risky)
## Classic Refactorings
### Extract Function
**Problem:** Function does too many things
```typescript
// Before: Long function doing multiple things
function processOrder(order: Order) {
// Validate order
if (!order.items || order.items.length === 0) {
throw new Error('Empty order')
}
if (!order.customer || !order.customer.email) {
throw new Error('Invalid