Skip to content

Instantly share code, notes, and snippets.

@iamhenry
Last active June 9, 2026 19:08
Show Gist options
  • Select an option

  • Save iamhenry/9efe8bfa14f8b5ca0ebd1654760c614b to your computer and use it in GitHub Desktop.

Select an option

Save iamhenry/9efe8bfa14f8b5ca0ebd1654760c614b to your computer and use it in GitHub Desktop.
General Purpose Refactor Prompt.md

How to think about refactoring

The mindset in one line

Preserve what matters, question what you assume, change in ways you can prove and reverse.

The practical loop

When refactoring, keep cycling through this:

  1. What is this code promising externally?
  2. What do I actually know vs assume?
  3. What evidence locks current behavior down?
  4. What is the smallest reversible improvement?
  5. What did this step prove or disprove?

That is a better SOP than rigid rules, because it helps when the situation is messy.

When To Use

Use this prompt when you’re refactoring existing code and want to avoid breaking hidden behavior.

  • Before changing legacy or messy code with unknown dependencies or weird edge cases.
  • When you need safer, incremental refactors instead of rewrites.
  • When preserving user-facing behavior matters more than making the code prettier.
  • When you want evidence-based changes, like tests or before/after outputs, not vibes.

When NOT To Use

Do not use this when you are doing a feature change or rewrite, not a true refactor that preserves behavior.

  • When you explicitly intend to change user-facing behavior or product rules.
  • When you are in a firefight bug fix and need the smallest, most direct patch.
  • When you lack any way to verify behavior (no tests, logs, or realistic data) and cannot safely add them first.
  • When a full replacement is already cheaper and safer than incremental changes.

1. Start with humility

Assume the code does more than you think.

Old code is rarely just “bad.” It often contains:

  • hidden business rules
  • workarounds for past bugs
  • weird behavior other parts now rely on

So the first stance is not “how do I improve this?” It is:

“What job is this code really doing today?”


2. Treat behavior as the asset, code shape as the tool

The point is not prettier code. The point is to keep useful behavior while making future change cheaper.

So always separate:

  • behavior = what users/callers experience
  • structure = how the code is organized internally

Refactoring means: preserve behavior, improve structure

If behavior changes, that is product work, not pure refactoring.


3. Think from the outside in

Do not begin with internals. Begin with impact.

Ask:

  • who depends on this?
  • what would they notice if I broke it?
  • what outputs, side effects, timing, errors, or data shapes matter?

This helps you see the true boundary.

Mental model: the outside is a promise, the inside is negotiable


4. Replace confidence with evidence

Never trust “this should still work.”

Use proof:

  • tests
  • before/after outputs
  • logs
  • real examples
  • observed usage

The right question is not: “Do I think this is safe?”

It is: “What evidence says this is safe?”


5. Reduce unknowns before reducing code

Messy code creates discomfort, so people rush to simplify it. That is where breakage happens.

First reduce uncertainty:

  • understand flows
  • map dependencies
  • observe inputs/outputs
  • identify what is stable vs accidental

Only then simplify.

Mental model: do not compress what you do not yet understand


6. Prefer reversible moves

A good refactor is easy to undo.

So think:

  • can I change this in small steps?
  • can I keep old and new paths briefly?
  • can I isolate one decision at a time?
  • can I roll back without drama?

This mindset naturally leads to safer moves.

Rule of thumb: if a step is hard to reverse, it is probably too big


7. Make one kind of change at a time

Mixing goals causes confusion.

Examples of mixed goals:

  • renaming + changing logic
  • extracting functions + changing API shape
  • cleanup + optimization + bug fix

When things go wrong, you lose the cause.

Better question: “What single problem am I solving in this step?”


8. Look for hidden contracts

The most dangerous part of refactoring is usually not the code you see. It is the dependency you do not see.

Ask:

  • is someone relying on this exact field name?
  • this error message?
  • this ordering?
  • this timing?
  • this null behavior?
  • this side effect?

A lot of “bad code” survives because it is quietly holding up something else.

Mental model: every strange line may be protecting a real-world assumption


9. Optimize for learning, not speed

Early in a refactor, your job is to learn. Later, your job is to improve.

So ask:

  • what is this code teaching me?
  • where am I still guessing?
  • what small change would reveal more?

This keeps you from forcing a clean design too early.


10. Think in seams

Do not think “rewrite module.” Think:

  • where can I separate concerns?
  • where can I introduce a boundary?
  • where can I swap one part without touching the rest?

A seam is just a place where change can happen safely.

Good refactoring is usually seam creation first, cleanup second.


11. Respect local ugliness if it preserves global stability

Sometimes the cleanest-looking change is the riskiest one.

Example:

  • adding a wrapper may feel less elegant than replacing everything directly
  • duplicating code briefly may be safer than forcing abstraction too soon

Temporary ugliness is acceptable if it buys safety and clarity.

Mental model: prefer awkward transition over elegant breakage


12. Finish by asking whether change got cheaper

The real test of good refactoring is not “does it look nicer?” It is:

  • is the code easier to reason about?
  • easier to test?
  • easier to change?
  • less coupled?
  • less surprising?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment