From refactoring
Use when restructuring code without changing behavior -- extracting functions, renaming, moving files, reducing duplication, migrating between patterns (JS to TS, CJS to ESM), or addressing code smells. Covers safe refactoring workflows for any language.
npx claudepluginhub sagargupta16/claude-skills --plugin refactoringThis skill uses the workspace's default tool permissions.
| Task | Approach |
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
| Task | Approach |
|---|---|
| Extract function/method | Identify repeated or complex block, extract with clear name |
| Rename safely | Find all references first, rename, run tests |
| Move file/module | Update all imports, check for re-exports, run tests |
| Reduce duplication | Extract shared logic only when used 3+ times |
| Migrate JS -> TS | File by file, start with strictest config, add types gradually |
| Migrate CJS -> ESM | Update require/module.exports to import/export, fix package.json |
| Simplify conditionals | Replace nested if/else with early returns or guard clauses |
| Smell | Symptom | Refactoring |
|---|---|---|
| Long function | > 30 lines or does multiple things | Extract method |
| Duplicate code | Same logic in 3+ places | Extract shared function |
| Deep nesting | > 3 levels of if/for/try | Early returns, extract helper |
| Long parameter list | > 4 parameters | Introduce parameter object |
| Feature envy | Method uses another class's data more than its own | Move method |
| God class/module | One file does everything | Split by responsibility |
| Dead code | Unreachable or unused code | Delete it |
| Primitive obsession | Raw strings/ints for domain concepts | Introduce value types |
| Shotgun surgery | One change requires editing many files | Consolidate related logic |
| Middle man | Class that only delegates | Remove and call directly |
Before:
def process_order(order):
# validate
if not order.items:
raise ValueError("Empty order")
if order.total < 0:
raise ValueError("Negative total")
# calculate tax
tax = order.total * 0.08
if order.state == "CA":
tax = order.total * 0.0975
order.tax = tax
order.final_total = order.total + tax
After:
def process_order(order):
validate_order(order)
order.tax = calculate_tax(order.total, order.state)
order.final_total = order.total + order.tax
def validate_order(order):
if not order.items:
raise ValueError("Empty order")
if order.total < 0:
raise ValueError("Negative total")
def calculate_tax(total: float, state: str) -> float:
if state == "CA":
return total * 0.0975
return total * 0.08
Before:
def get_payment(employee):
if employee.is_active:
if employee.is_full_time:
if employee.years > 5:
return employee.salary * 1.1
else:
return employee.salary
else:
return employee.hourly_rate * employee.hours
else:
return 0
After:
def get_payment(employee):
if not employee.is_active:
return 0
if not employee.is_full_time:
return employee.hourly_rate * employee.hours
if employee.years > 5:
return employee.salary * 1.1
return employee.salary
Before:
function createUser(name: string, email: string, age: number, role: string, team: string) { ... }
After:
interface CreateUserParams {
name: string;
email: string;
age: number;
role: string;
team: string;
}
function createUser(params: CreateUserParams) { ... }
.js to .ts (one file at a time, start with leaf modules)tsconfig.json with strict modeunknown over any when the type is genuinely unclear| CJS | ESM |
|---|---|
const x = require('x') | import x from 'x' |
const { a } = require('x') | import { a } from 'x' |
module.exports = x | export default x |
module.exports.a = a | export { a } |
__dirname | import.meta.dirname (Node 21+) or fileURLToPath |
__filename | import.meta.filename (Node 21+) or fileURLToPath |
Also update package.json: add "type": "module".
| Class | Functional |
|---|---|
this.state / setState | useState |
componentDidMount | useEffect(..., []) |
componentDidUpdate | useEffect(..., [deps]) |
componentWillUnmount | useEffect cleanup return |
this.props | Function parameters |
shouldComponentUpdate | React.memo |
refactor: rename X to Y for clarity| Situation | Why |
|---|---|
| Code is being deleted soon | Wasted effort |
| No tests exist for the code | Refactor tests first, then code |
| Mixed with a feature change | Do separately -- refactor first, then add feature |
| "While I'm here" improvements | Stay focused on the task at hand |
| Premature abstraction | Wait until pattern repeats 3+ times |
| Don't | Do Instead |
|---|---|
| Refactor and change behavior in one commit | Separate commits: refactor first, then change behavior |
| Extract a helper used only once | Inline is fine for single-use code |
| Create deep abstraction hierarchies | Prefer composition and flat structures |
| Rename without searching all references | Grep the entire codebase first |
| Refactor without passing tests | Fix or write tests first |
| "Clean up" code you're not working on | Only refactor code related to your current task |