Refactoring With AI Without Losing Your Mind

Categories: ai, engineering, refactoring


Refactoring a system is already dangerous.

Refactoring a system with AI in the loop?

That can either be a superpower… or a fast track to chaos.

After working through a full layout and styling refactor on this blog, I started to notice a pattern—not just in what worked, but in what kept me from completely losing the thread halfway through.

This isn’t a post about “AI made this easy.”

It didn’t.

This is about how to work with AI deliberately so you don’t create something your future self hates.


1. The Trap: Letting AI Lead the Architecture

The easiest mistake to make is also the most tempting:

“Here’s my code. Improve it.”

AI will happily:

  • rename things
  • restructure files
  • introduce new abstractions
  • suggest patterns that look cleaner

And suddenly…

You’re no longer refactoring.

You’re rewriting—without a clear mental model of what changed.

That’s where things break down:

  • styles drift
  • layout assumptions conflict
  • debugging becomes guesswork
  • your “simple change” becomes a multi-hour spiral

2. The Shift: You Own the Model, AI Executes

The turning point for me was simple:

Stop asking AI what to do. Start telling it what you’ve already decided.

Before touching code, I had to answer:

  • What is my layout model?
  • Where is the source of truth for spacing and width?
  • What is mobile-first actually enforcing here?
  • What must not change?

Only after that did AI become useful.

Instead of:

“Fix my layout”

I moved to:

“Act as a CSS/layout debugger. Identify the current model, then propose the minimum changes required to center the reading canvas.”

That one constraint changed everything.


3. The Real Superpower: Constraint-Driven Iteration

AI is incredible at operating within constraints.

But you have to give it constraints.

The most effective loop I found looked like this:

Step 1: Snapshot Reality

  • Current source files
  • Generated output (in my case, Jekyll build)
  • Screenshots of actual rendering

Step 2: Force Reconciliation

Ask AI to:

  • reconcile HTML + CSS + output
  • identify the actual layout system in play

Not what we think is happening.

What is happening.

Step 3: Demand Surgical Changes

Not:

“Refactor this”

But:

“Propose the minimum patch set required to achieve X”

Step 4: Apply Incrementally

  • Patch 1–3 files
  • Rebuild
  • Validate visually
  • Repeat

This prevented the classic AI failure mode:

Warning “Everything changed, and I don’t know why.”

What This Looked Like In Practice

In this blog refactor, constraints were not abstract. They were specific:

  • keep semantic HTML
  • go mobile-first
  • move to a token-first theme model
  • hit WCAG AA contrast in both light and dark modes

A few moments made the value of this process obvious:

  • Theme drift prevention: We added a repeatable contrast check workflow instead of relying on visual guesses.

  • UI regression recovery: Mobile nav looked better after a pass, but accidentally occluded page content when opened. Fixing it was straightforward because scope stayed tight: remove the global overlay, keep panel-level separation, re-test.

  • Scope discipline: We intentionally deferred connect page changes to a separate pass instead of folding it into every other layout change. That kept the main refactor understandable and reviewable.

  • Layout sanity over cleverness: We removed overlapping style assumptions, normalized spacing rules, and made behavior explicit by breakpoint.

None of that is flashy, but that is exactly the point. The trust in AI went up as the constraints got tighter, not looser.


3.5. The Execution Layer: Working Directly in the Code with Copilot

Everything above describes the thinking model.

But the execution layer matters just as much. This is where the feedback loop lives.

One of the biggest accelerators in this process was shifting into a workflow where AI could operate directly on the codebase, not just through chat.

Using Copilot with GPT-5.3 in VS Code changed the feedback loop in two important ways:

Planning Mode → Agent Mode

The flow became:

  1. Planning Mode
    • Define constraints
    • Clarify intent
    • Break work into scoped changes
  2. Agent Mode
    • Apply changes directly to the code
    • Navigate files automatically
    • Execute multi-step edits without losing context

This removed a major source of friction:

Warning Copy → paste → modify → re-run → repeat

Instead, iteration became:

Pro Tip Think → constrain → apply → validate

Why This Worked

The key difference wasn’t just speed.

It was context continuity.

Because the AI could:

  • see the actual file structure
  • follow imports and dependencies
  • modify multiple files in one pass

…it stopped behaving like a suggestion engine and started behaving like a constrained executor.

The Important Caveat

This only worked because the constraints were already defined.

Without that, agent mode becomes dangerous very quickly:

  • large, unfocused changes
  • unintended side effects across files
  • loss of architectural clarity

In other words:

Warning Agent mode amplifies your system.

If your thinking is clear, it accelerates you. If your thinking is fuzzy, it magnifies the chaos.

The Net Effect

This shift dramatically shortened the feedback cycle:

  • faster iteration
  • fewer context resets
  • tighter alignment between intent and implementation

But it didn’t replace the core loop.

It just made it faster to execute the same disciplined loop.

The discipline still came first.


4. Maintainability Is the Only Metric That Matters

It’s easy to get something that looks right.

That’s not the goal.

The goal is:

Can I come back in 3 months and understand this in 30 seconds?

That forced a few principles:

  • No overlapping layout systems (Water.css + Pico + custom overrides = pain)

  • Semantic HTML first, styling second

  • Single source of truth for layout width

  • Kill cleverness early

If something felt “kind of magical,” it was probably a future bug.


5. AI Is a Force Multiplier for Discipline (Not a Replacement)

AI didn’t remove the need to think.

It made lack of thinking more dangerous.

When used well, it becomes:

  • a second set of eyes
  • a fast iteration engine
  • a way to validate assumptions

When used poorly, it becomes:

  • a chaos generator
  • a source of silent complexity
  • a confidence trap

6. What I’d Do Again (and What I Wouldn’t)

I would:

  • Start with constraints before code
  • Treat AI as a debugger, not a designer
  • Work in small, validated patches
  • Continuously compare source vs output

I would not:

  • Accept large, multi-file rewrites blindly
  • Mix design systems without a clear boundary
  • Assume AI understands my intent without explicitly stating it

7. The Meta Takeaway

The most valuable shift wasn’t technical.

It was mental:

I stopped collaborating with AI like a peer, and started directing it like a system.

That’s when it became reliable.


What’s Next

I’m planning to document this process more visually:

  • before/after layout diagrams
  • CSS cascade breakdowns
  • “what changed vs what I thought changed”

Because the real lesson here isn’t about CSS.

It’s about how to think clearly while moving fast with AI— whether that AI is in a chat window or directly modifying your code.

And that’s a skill that’s only going to matter more.