Refactor a Legacy Function Safely
Get a staged refactor plan for a function you are afraid to touch — characterisation tests first, then small commits, each independently revertible.
The Prompt — replace [BRACKETS] with your details
Act as a staff engineer who has cleaned up a lot of legacy code and broken production exactly once. Plan a safe refactor. The code: ```[LANGUAGE] [PASTE THE FUNCTION OR MODULE] ``` Context: - What it does, as far as I know: [DESCRIPTION] - Who calls it: [CALLERS, OR "unknown"] - Test coverage today: [NONE / SOME / DESCRIBE] - Why I am touching it: [BUG / NEW FEATURE / PERFORMANCE / IT IS UNREADABLE] - What must not change: [PUBLIC BEHAVIOUR, API SHAPE, PERFORMANCE BUDGET, SIDE EFFECTS] Deliver: 1. A plain-language description of what this code currently does, including the behaviour that looks accidental but that callers may depend on 2. The characterisation tests to write BEFORE changing anything — the specific cases that pin down current behaviour, including the ugly edge cases 3. A refactor sequence of small steps, each one a commit that keeps the tests green and can be reverted on its own. No step should change behaviour and structure at the same time 4. For each step: what changes, what could break, and how the tests catch it 5. The parts you would leave alone, and why — call out where the risk is not worth the tidiness 6. Anything in the code you genuinely cannot understand from what I pasted, listed as a question for me rather than an assumption Do not give me the finished refactored file. I want the sequence.
How to use this prompt
- Write the characterisation tests first and watch them pass against the unchanged code — that is what makes the rest safe.
- Do one step per commit. A ten-file refactor that fails is a bisect nightmare.
- Answer the questions in section 6 before starting; they are usually where the real bug is hiding.
Why this prompt works
Asking a model to "refactor this" produces a rewrite you cannot review and cannot bisect. Asking for a sequence with tests first inverts that: you keep the review small at every step, and the accidental-behaviour section addresses the specific way legacy refactors break callers nobody knew about.
Variations to try
- Add "this is called from a public API with external consumers" to get a stricter compatibility analysis.
- Ask for the characterisation tests written out in your test framework, then work step by step yourself.
- After each step, paste the diff back and ask what behaviour could have changed.
Common mistakes to avoid
- Taking a wholesale rewrite because it looks cleaner, then spending a week finding the behaviour you dropped.
- Skipping characterisation tests because "the code is simple". It is not, or you would not be nervous.
- Mixing a rename with a logic change in one commit, making the review useless.
Works well with
Need a custom version of this prompt?
The free prompt generator builds a prompt tailored to your exact goal, framework, and target AI model — or paste this template into the optimizer to refine it.
Related prompts
Code Review Assistant
Paste code and get a structured review covering bugs, readability, performance, and securi…Debug Any Error Message
Paste an error message and the related code to get the likely root cause, a fix, and how t…Unit Test Generator
Generate thorough unit tests for any function, covering happy paths, edge cases, and failu…Code Documentation Writer
Generate clear docstrings, inline comments where needed, and a README-style usage section …Sponsored
Revenue Signal
Visitor → payment → MRR
MRR
$9.4k
+18%
ARR
$112k
run rate
Net New
+$1.7k
this month
Subs
192
active
ARPU
$49
per account
Churn
3.2%
watchlist
new MRR
+$1.9k
expansion
+$620
reactivation
+$210
churn + contraction
-$790
Failed Payments
$820 at risk
Open Metrics
public page ready
Click-worthy signal
Turn the traffic your content earns into real revenue — see which visitors actually convert.
Find my MRR signal →