Refactor a long, tangled function into smaller, testable units
Breaks an overgrown function into smaller, single-responsibility units while preserving behavior and the public signature.
Long functions are where bugs hide and onboarding slows down. The hard part of refactoring is doing it safely—changing structure without changing behavior—and most AI 'refactors' quietly alter the public signature or drop an edge case. This prompt forces a behavior-preserving approach: it pins the public signature so callers keep working, asks for single-responsibility extractions, and demands that hidden side effects be flagged rather than silently moved around. It works best when you give the model the actual code plus any hard constraints (no new dependencies, must stay synchronous, keep the same error type). Because it asks for a one-line explanation per extraction and a change summary, you get a reviewable diff rather than a mystery rewrite. Use it as a first pass before you run your test suite; the model is a refactoring assistant, not a substitute for the green checkmark. Pair it with the unit-test prompt so you have a safety net before and after the change.
You are an expert software engineer who specializes in safe, behavior-preserving refactoring. I will give you a function written in [LANGUAGE] that has grown too long and does too much. Refactor it into smaller, well-named functions with clear single responsibilities, without changing observable behavior. Preserve the existing public signature [PUBLIC_SIGNATURE] so callers do not break. Extract pure helpers where possible, remove duplication, and flag any hidden side effects you find. Explain each extraction in one line. Honor these constraints: [CONSTRAINTS]. Here is the function: [FUNCTION_CODE] Return the refactored code first, then a short bullet list of what changed and why.
What you can expect back
```ts
function calculateInvoice(order: Order): Money {
const subtotal = order.items.reduce((sum, item) => sum + lineTotal(item), 0);
const total = clampToZero(applyCoupon(subtotal, order.coupon));
return { amount: total, currency: order.currency };
}
function lineTotal(item: LineItem): number {
if (!item.sku) throw new ValidationError('missing sku');
const gross = item.price * item.qty;
return item.qty >= 10 ? gross * 0.9 : gross;
}
function applyCoupon(amount: number, coupon?: string): number {
return coupon === 'SAVE5' ? amount - 5 : amount;
}
const clampToZero = (n: number) => (n < 0 ? 0 : n);
```
Changes:
- Extracted lineTotal: isolates validation + bulk discount per item.
- Extracted applyCoupon: separates discount policy from summation.
- Added clampToZero helper for the negative-total guard.
- Public signature and ValidationError type unchanged; no new deps.Illustrative example — your results will vary by tool and inputs.
Get sharper results
- 01Run your test suite immediately before and after—this prompt preserves behavior by intent, not by proof.
- 02If the function has side effects (DB writes, logging), list them in [CONSTRAINTS] so they aren't reordered.
- 03Ask for the diff in a second message if the rewrite is large, so review stays focused.
- 04Refactor in small batches; feed one function at a time rather than a whole file.
Adapt it for your case
Add 'Prioritize reducing branching depth; replace nested conditionals with guard clauses or a lookup table.'
Add 'Extract impure operations behind injectable parameters so the core logic can be unit-tested without mocks.'
Common questions
Will it change my function's behavior?
The prompt instructs behavior-preserving refactoring, but always confirm with your existing tests—treat the output as a proposal, not a guarantee.
Can I refactor an entire file at once?
Better not. Feed one function at a time; large multi-function rewrites are harder to review and more likely to drift.
What if it suggests a new dependency I don't want?
List 'no new dependencies' in [CONSTRAINTS]; the prompt already respects stated constraints and will work within the standard library.
You may also need
Perform a Thorough Code Review on a Pull Request
Get a senior-engineer-style code review with categorized, file-referenced feedback.
Refactor Code for Readability and Maintainability
Refactor any code for readability and maintainability without changing its behavior.
Audit Code for Performance Bottlenecks
Identify performance bottlenecks in code and get ranked, impact-focused optimization suggestions.
Run a Security Review on Code
Get an OWASP-aligned security review with severity ratings and remediation snippets.