Refactoring with AI: Why “Fix Everything” Is a Terrible Prompt

Published:22 May 2025 - 5 min. read

I learned this lesson the hard way. Several times, actually. And I’ve got the git history to prove it.

There I was, staring at a React component that had ballooned to over 500 lines. You know the type – started simple, then grew tentacles as features got tacked on. The classic “I’ll clean this up later” that never happened. We’ve all been there, right?

With Claude in my corner, I figured I’d just say “Hey, refactor this entire component,” and watch the magic happen. I mean, why not? That’s what AI is for, right?

Wrong. So very wrong.

The Great Refactoring Disaster

“Refactor this component to be more modular and maintainable,” I told it confidently, leaning back in my chair with a smug grin, already imagining how impressed my team would be.

Claude spat out a beautiful-looking refactor. Custom hooks extracted. Logic separated. Props destructured neatly. It even added JSDoc comments. On the surface, it looked like exactly what I wanted.

I copied it in, ran the app, and… nothing loaded. Not just the component – three different pages broke. That smug grin? Gone. Replaced with pure panic.

Turns out, the AI had silently broken state handling across multiple components. It renamed some key variables but missed references elsewhere. It removed what looked like duplicate code that actually handled subtle edge cases.

The worst part? Fixing it took me longer than if I’d just refactored manually. I could have used git to revert the change, but some parts were actually working well that I wanted to keep. The changeset was so big I couldn’t just keep one piece and discard the rest.

Since everything was tangled together in one massive update, I had to keep it all and fix it manually. I spent hours tracing through the changes, trying to figure out what went wrong, before finally accepting defeat and starting over.

Why AI Fails at Large Refactors

After a few more painful experiments (because apparently I’m a glutton for punishment), I realized why asking AI to “fix everything” fails:

  • It loses context across large files. AI struggles to keep track of all the interconnections in complex code. It’s like asking someone to reorganize your garage without telling them which cables connect to which devices.
  • It doesn’t truly understand your architecture. It can’t see how that one function affects three other components. It’s working in isolation while your app is an ecosystem.
  • It makes silent trade-offs. It might prioritize cleaner structure over maintaining every feature, dropping things it thinks are unimportant. But who gave it permission to decide what’s important?
  • It restructures based on patterns, not business logic. It will happily create elegant abstractions that completely miss the point of what your code needs to do. Pretty code that doesn’t work is still broken code.

The results are predictable:

  • Broken references (like when you rename a variable but forget to update it everywhere)
  • Missing side effects (goodbye, analytics tracking!)
  • Over-engineered simple code (three hooks for what used to be five lines)
  • Silently dropped functionality (it’s not a bug, it’s a feature… that’s now missing)

A Better Way: Create an AI Refactoring Framework

After those painful lessons, I’ve since learned a few things about taking small bites off of this elephant that usually help. And by usually, I mean when I actually follow my own advice instead of getting impatient.

Step 1: Establish a Git Baseline

This one’s obvious but I still forget half the time. Make a clean branch. Commit. This is your panic button for when things go sideways.

Phase 1: Review First

Instead of “fix everything,” I start with:

Review this code and create a Markdown file of what should be improved or modularized. Don't rewrite anything yet.

This forces AI to analyze without changing, giving me a roadmap instead of a replacement. Creating something concrete like a file allows you to use an artifact to collaborate with AI on.

It’s like asking someone to look at your messy garage and make a list of what needs organizing before they start moving things around. Way less dangerous.

Phase 2: Human Feedback

Once the list is in place, I’ll review that list myself and:

  • Cross off anything unnecessary (“No, I don’t need to convert every function to an arrow function, thanks”)
  • Add my own priorities (“This state management is the real problem”)
  • Mark risky changes (“Don’t touch the payment processing logic!”)

This keeps me in control of the process. The AI is still just a tool, not the decision-maker. Even if I don’t know what the hell I’m doing (half the time), I’ll make a note like “fix this to the best of your knowledge” to rely on the model’s expertise instead of mine (or lack thereof).

Phase 3: Break It Down

Next, I split the checklist into small, manageable chunks. For example:

  1. Extract form validation logic to a custom hook
  2. Create separate components for each form section
  3. Refactor state management

The key: I only tackle ONE item at a time. One. Singular. Uno. This is the difference between success and disaster.

It’s like eating an elephant – one bite at a time. Try to swallow it whole and you’ll choke. (Not that I advocate eating elephants. Please don’t.)

Phase 4: Execute in Isolation

For each task:

  • Work in a branch (see Step 1, which I still forget sometimes)
  • Give AI very specific instructions like “Extract only this block into a hook called useValidation. Don’t change anything else.”
  • Commit after each successful change

Basically, treat AI like that new junior dev who’s really eager but sometimes misunderstands requirements. You wouldn’t tell them “refactor the whole app” on day one, would you?

Phase 5: Verify and Restore

After each change:

  • Run tests (you have tests, right? …right?)
  • Check functionality manually (click all the buttons, fill all the forms)
  • If something breaks: roll back and retry with a more limited scope
  • If it works: check it off the list and continue

This cycle keeps you from getting too far down a broken path. It’s like driving with regular checkpoints instead of waiting until you’re completely lost to check the map.

Tips That Save Me Every Time

  • Use breadcrumb comments: Add comments like // Handles form validation to help AI understand what code does. It’s like labeling the boxes in your garage before asking someone to reorganize it.
  • Keep it scoped: Say “Only extract this function, don’t change variable names” instead of “Clean this up.” Be bossy and specific. AI doesn’t have feelings to hurt.
  • Expect failure: Use Cursor checkpoints, Git, or just keep the original code in a separate file. Assume things will break and plan for it.
  • Build incrementally: Successful refactoring happens step by step, not all at once. This is true with or without AI, but AI makes it even more critical.

The Real Magic of AI Refactoring

Once I started breaking things down this way, I found the sweet spot. AI went from being my demolition crew to my junior developer.

It’s excellent at:

  • Extracting a single function to a hook (it can handle this transformation beautifully)
  • Converting class components to functional ones (when guided)
  • Implementing a pattern you describe in detail
  • Adding type definitions or documentation (seriously, it’s amazing at this)

It’s terrible at:

  • Understanding your entire codebase (it doesn’t have the context)
  • Making architectural decisions (it doesn’t know your business needs)
  • Knowing which edge cases matter to your users
  • Preserving business logic it doesn’t understand (that weird exception for California users? Gone.)

Final Thoughts

Refactoring with AI isn’t about asking it to “fix everything.” It’s about using AI as a force multiplier for your own expertise.

Break down the work. Give specific instructions. Keep a rollback plan.

The AI isn’t the architect – you are. The AI is just a really smart keyboard that can write code faster than you can type. Once you embrace that reality, refactoring with AI becomes not just possible, but incredibly powerful.

Just remember: one change at a time. And maybe, just maybe, create that git branch first.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!