NeuralOS
GuideAdvanced

AI code surgery · the 7-phase protocol that leaves your app spotless on the inside

AI is a lightning-fast bricklayer: it raises a wall in seconds. But it leaves rubble everywhere — dead code nobody calls, the same logic copied across five places, `any` scattered like salt, animations that make the GPU sweat. On the outside your app looks beautiful; on the inside it's rusting. This resource gives you the 7-phase protocol that turns your AI agent into a surgeon: it goes into the code, removes the dead parts, merges the duplicates, fixes the animations, tunes React performance, banishes the `any`, calms the GPU down — and comes out without having touched a single pixel of what the user sees. The rule is sacred: zero visual changes, zero behavioral changes. Only the inside gets cleaned. I'll explain when it's needed, why AI makes a mess, the habit that keeps it from rotting, and ONE master prompt you hand it so it operates phase by phase.

Jul 19, 202614 min
Who is this for?
For anyone who has been building with AI for weeks or months and feels like the app isn't as easy to touch as it was at the start. Adding a small feature got slow, weird bugs show up, the AI gets lost in its own code. It's not you: it's the code, which got dirty because nobody cleaned it up. This resource is the deep clean — the surgery that leaves it spotless on the inside without changing anything you see on the outside. You don't need to code: you need to know what to ask your agent for, and in what order.

1. The moment: when the app works on the outside but creaks on the inside

At first it's all magic. You tell the AI "add a profile screen" and it appears. "Now an export button," and it appears. You move fast, really fast. But there's a moment — almost always between the third and tenth week — when something shifts. Asking for a small feature is no longer instant. The AI takes longer, gets confused, touches things it shouldn't. Bugs pop up in places you never even touched. The app works, but moving it got heavy, like walking with mud on your shoes.

That's THE moment. Nothing dramatic happened: nothing visible broke. What happened is invisible and it's called technical debt. The AI built fast and, like anyone who builds fast, it left rubble behind: code nobody uses anymore but that's still there, the same logic copied across five files, any types that switch off every alarm, animations thrown together any which way. None of that shows up on screen. All of it makes every future change harder.

Picture it this way
A surgeon doesn't change your face. They go in, fix what's inside — remove what's in excess, stitch it up right, reinforce the weak spots — and you come out with the same face as before, but healthy on the inside. Code surgery is exactly that: nobody using your app will notice a single change, but on the inside it comes out clean, typed and rubble-free. If something looks different afterward, it wasn't surgery: it was an accident on the operating table.

2. The pain: where it comes from and why AI makes a mess (even when it writes "well")

Here's the important, honest part: AI doesn't write bad code. It writes code that works. The problem is that it optimizes for "make it work now," not for "make it easy to maintain three months from now." And those two things pull in different directions. That's why, even though every piece is fine, the sum gets dirty. These are the four kinds of rubble it leaves, and why it leaves them:

Where the mess comes from (the four kinds of rubble)
Dead code. You ask for a change, the AI rewrites a fresh function… but forgets to delete the old one. It stays there, orphaned, with nobody calling it. Multiply that by hundreds of changes and you've got entire files that no longer serve any purpose.
Duplication. The AI doesn't always remember it already wrote that same logic before, so it writes it again. Now the same rule lives in five places. The day the rule changes, you have to fix it five times — and you always miss one.
`any` and loose types. When the AI isn't sure of a value's type, it takes the shortcut: it marks it as any. With that, it switches off every alarm TypeScript has for warning you about errors. The code compiles… and blows up in production.
Animations and effects thrown together roughly. The AI drops in animated gradients, blurs, shadows — they look good, but poorly built they make the GPU sweat, and the app feels slow on phones and modest laptops.
The real pain: a slow accident, not an apocalypse
None of this is going to take your app down tomorrow. It's more treacherous than that: it's slow erosion. Every week it costs a little more to add things, the AI slips up a little more often, bugs show up a little more. There's no disaster day; there's a gradual slide toward code that's scary to touch. Surgery halts that erosion before the project becomes impossible to move.
What happens if you DON'T do it
If you never clean up, you reach the point where the AI itself drowns in your code. When there's so much duplication and so much dead code, the AI doesn't know which of the five copies is the right one, or it touches the orphaned function instead of the live one, and it introduces new bugs while fixing the old ones. Dirty code doesn't just slow you down: it slows down the very tool that builds it. Surgery hands the AI back a clean canvas to keep working on.

3. The 7 phases of the surgery (the heart of it all)

A surgeon doesn't cut open and poke around at random: they follow a protocol, in order, step by step. Code surgery is the same. There are seven phases, and the order matters: first you remove the dead code (so you don't clean up code you were going to delete), then you merge duplicates, then you harden animations, then React performance, then the types, then you calm the GPU down, and at the end you issue a health report. Here's each one.

Phase 1 · Remove dead code

The first thing is to clear off the table everything that no longer breathes. It's the most rewarding phase because it clears the ground for all the others: there's no point optimizing a function you're about to delete.

What gets hunted in Phase 1
Orphaned files — files nobody imports from anywhere. They're there from an old version that never got deleted.
Exports with no consumers — functions or components that are exported but nobody uses. They got exported "just in case" and the just-in-case never came.
Unused variables, functions and imports — declared and forgotten. The linter usually flags them, but the AI leaves them because "they don't bother anyone." They do bother: they're noise.
Unreachable code branches — conditions that can never be true, code after a return, if statements nobody triggers anymore.
The safety net before deleting
Deleting is nerve-wracking — what if that was actually being used? That's why the number-one rule of this phase: make a commit on GitHub before you start. If the surgery deletes something that was needed, you roll back with one click. Never operate without a net. (At the end I'll leave you the GitHub resource as your undo button.)

Phase 2 · Audit duplicates

With the ground cleared, now you hunt for what's repeated. The rule of the trade is simple: if something shows up three times or more, it stops being coincidence and becomes a pattern that deserves a single place to live.

The four kinds of duplicate and their cure
Repeated logic → pull it out into a helper that both places call. One rule, one single place.
Repeated magic numbers and strings (the same 48, the same URL, the same color) → centralize them into named constants. You change once, it changes everywhere.
JSX repeated three or more times (the same card, the same button with slight variants) → turn it into a subcomponent that receives its differences via props.
The `useState` + its handler pattern, repeated (the same state with its update function copied across several components) → extract it into a custom hook that encapsulates the logic just once.
The limit of refactoring
Careful not to overdo it. Not everything that looks alike is the same. Two pieces that look identical TODAY but change for different reasons must not be merged — joining them creates a coupling that hurts more later than the duplication did. The rule: merge what changes for the SAME reason. When in doubt, two clear copies beat one confusing abstraction.

Phase 3 · Enforce the animation rules

Animations are where the AI improvises the most and where it leaves the most subtle glitches — things that don't break but that make the app feel "cheap": flickers, jumps, transitions that don't kick in. These are the concrete rules the surgery checks (they apply to React animation libraries like Motion / Framer Motion, the ecosystem standard):

The 5 animation rules that get audited
Animating to/from `transparent` can flicker → use rgba(0,0,0,0) instead. When you interpolate the word transparent with a color, the transition can produce an ugly flicker halfway through; rgba(0,0,0,0) interpolates cleanly.
No duplicate `transition` — an animation with two transition definitions fighting each other gives an unpredictable result. One single source of truth for the timing.
Don't animate the `border` shorthand (the shorthand that bundles width, style and color) → animate separate properties like borderColor. The shorthand doesn't interpolate cleanly.
`background` → `backgroundColor` in animations — animating the full background shorthand is problematic; animate only the specific property that changes.
Stable keys in lists that enter and exit (AnimatePresence) — if the items in an animated list don't have a stable, unique key, the exit animations break and elements jump. The key must be a real id, never the array index.

Phase 4 · React performance

Here the surgery hunts for the work React repeats without need. Every unnecessary re-render is a little bit of slowness; added up, they make the app feel heavy. Four concrete things get reviewed:

The 4 React performance checks
Handlers passed as props without `useCallback` → wrap them. Otherwise, every render creates a new function and forces child components to re-render even though nothing changed.
Expensive computations without `useMemo` (filtering/sorting a big list, heavy calculations) → memoize them. Otherwise, they get recalculated on every render even when the data is identical.
`useEffect` with badly declared dependencies — too many dependencies fire the effect for no reason; too few make it use stale data. Both are bugs. The dependency array must list exactly what the effect uses.
`.map` without a stable `key` — rendering lists without a unique key (or using the index) makes React get confused when reordering and lose state. Each element needs its own id.
Optimizing isn't slapping memoize on everything
The beginner mistake in this phase is wrapping EVERYTHING in useCallback and useMemo "just in case." No: memoizing has a cost too (memory, complexity). The surgery only memoizes where there's a real, measurable benefit — a handler that flows down to many children, a genuinely expensive computation. Over-optimizing is its own kind of mess.

Phase 5 · TypeScript hygiene

TypeScript is your code's alarm system: it warns you before an error reaches the user. But it only works if you let it see the types. Every any is an alarm someone switched off. This phase switches them back on.

The type cleanup
`any` → a real type, or `unknown`any disables every check. If you truly don't know the type, use unknown, which forces you to verify it before using it (safe), instead of any, which forces nothing (dangerous).
Review the `as Type` casts — telling TypeScript "trust me, this is of this type" is a promise that can be a lie. Every as is a spot where the compiler stopped checking. Review them one by one: is it true, or is it a patch?
Internalize single-use exports — if a type or function is exported but only used within its own file, it shouldn't be public. Drop it to private: less surface, less noise.
Type your component props — every component should declare which props it receives and of what type. Untyped props are any in disguise.

Phase 6 · Audit the GPU collapse

This is the phase almost nobody knows about and the one that shows up most on modest devices. Certain visual effects are gorgeous but brutally expensive to draw: if you overuse them, the graphics card gets saturated and the app stutters. The surgery hunts for the three classic culprits:

The 3 silent GPU killers
Animated conic gradient (`conic-gradient`) → move it to a CSS animation with @keyframes. Animating a conic gradient via JavaScript on every frame is dead expensive; with keyframes the browser optimizes it.
Lots of `repeat: Infinity` (several infinite-loop animations at once) → consolidate them. Ten endless animations running in parallel keep the GPU awake and burning battery nonstop. Merge them or cut the ones you don't really need.
`backdrop-blur` on lots of small repeated elements → if the same background blur repeats across twenty little cards, the GPU recalculates it twenty times. For small, repeated elements, a solid (or semi-transparent) background looks almost the same and costs a fraction.
Why blur hurts
Background blur (backdrop-blur, that trendy frosted-glass effect) forces the GPU to look at EVERYTHING behind the element and blur it in real time. One single big one, no problem. Twenty small ones repeating is like asking the card to blur the screen twenty times per frame. That's where your user's laptop starts spinning up the fan.

Phase 7 · The health report

Every surgery ends with a report. Without a report you don't know what was touched, and you can't trust that there was no collateral damage. The last phase is the agent handing you a clear summary, in your own language, of everything it did:

What the final report must include
Count per phase — how many orphaned files, how many duplicates merged, how many any removed, how many animations fixed, etc.
Lines purged — the total of dead code lines that came out. It's the most satisfying number: code you no longer have to maintain.
A "production-ready" verdict — the explicit confirmation that nothing visual or behavioral was changed, only internal structure.
What it did NOT touch and why — the things that looked like candidates but were deliberately left alone (duplicates that change for different reasons, memoize that wasn't worth it). The honesty of what it decided not to do.
The sacred rule of the whole surgery
Repeat it like a mantra and put it in every prompt: ZERO visual changes. ZERO behavioral changes. The app has to look and behave EXACTLY the same before and after. If a button moved one pixel, if a flow changed, if something stopped working — that wasn't surgery, it was a wound. When torn between cleaning more and preserving behavior, preserving behavior always wins.

4. The habit: surgery is maintenance, not a one-off operation

The most common mistake is thinking of surgery as something you do once, when everything is already a disaster. No. AI code gets dirty CONTINUOUSLY, because every build session leaves fresh rubble. Surgery isn't an emergency operation: it's the teeth cleaning you do every six months so you never end up needing a root canal.

The moments when it's ALWAYS worth operating
After a big build sprint — when the AI has just generated a lot of code all at once, that's the fresh rubble. Clean it before more piles on top of it.
Before starting an important feature — give the AI a clean canvas to build on. On dirty code, it builds dirty.
When you notice the AI starting to get confused — if the tool touches things it shouldn't or gets lost, that's a sign there's too much noise. Surgery gives it back its clarity.
One file or module at a time, not the whole project at once — operating on a single module is safe and reviewable. Operating on everything at once is open-heart surgery without anesthesia. Go in parts.
The line that sums it up
The mistake isn't that the AI dirties the code — that's unavoidable, building fast always leaves rubble. The mistake is never cleaning it up. Constant surgery is what separates a project that gets easier to touch over time from one that becomes untouchable.

5. The master prompt · hand it to your agent and operate phase by phase

Here's the key piece: ONE single prompt that turns your code agent into a surgeon who applies the 7 phases, in order, to a file or module — without touching anything visual. Fill in the [brackets], paste it, and let it operate. One tip before you start: make a commit on GitHub first (your safety net) and point it at ONE module, not the whole project.

Master prompt · the 7-phase code surgerytexto
Act as an expert debugging code surgeon. You are going to operate on this file/module: [FILE OR FOLDER PATH, e.g.: src/components/Dashboard/]. The stack is: [e.g.: React + TypeScript + Motion/Framer Motion + Tailwind].

SACRED, INVIOLABLE RULE: ZERO visual changes and ZERO behavioral changes. The app must look and behave EXACTLY the same before and after. You only clean and harden on the inside. In any doubt between cleaning more or preserving behavior, preserving behavior ALWAYS wins. Don't delete anything unless you're sure it's not used; flag it and ask me.

Apply these 7 phases IN ORDER. Don't move to the next one without finishing the previous one. At the end of each phase, tell me in one line what you found and what you changed.

PHASE 1 — DEAD CODE: remove orphaned files (that nobody imports), exports with no consumers, unused variables/functions/imports, and unreachable code branches. Before deleting anything doubtful, list it for me and wait for my confirmation.

PHASE 2 — DUPLICATES: hunt for repeated logic (→ extract into a helper), repeated magic numbers/strings (→ named constants), JSX repeated 3+ times (→ subcomponent with props), and the repeated useState+handler pattern (→ custom hook). DON'T merge things that only look alike but change for different reasons.

PHASE 3 — ANIMATION RULES: fix transparent→rgba(0,0,0,0), remove duplicate transition, don't animate the border shorthand (use borderColor), change background→backgroundColor in animations, and ensure stable, unique keys (never the index) in lists with AnimatePresence.

PHASE 4 — REACT PERFORMANCE: wrap in useCallback the handlers passed as props, memoize expensive computations with useMemo, fix the useEffect dependency arrays (neither too many nor too few), and add a stable key to every .map. DON'T memoize just in case: only where there's a real benefit.

PHASE 5 — TYPESCRIPT: replace each any with a real type or with unknown; review every 'as Type' cast (is it true or is it a patch?); internalize the exports only used within their own file; and type the props of every component.

PHASE 6 — GPU COLLAPSE: move animated conic gradients to CSS @keyframes; consolidate the repeat:Infinity ones if there are many at once; and replace backdrop-blur with a solid/semi-transparent background on small elements that repeat many times.

PHASE 7 — HEALTH REPORT: when you finish, hand me a report with: count per phase, total lines purged, the explicit confirmation that you didn't change anything visual or behavioral, and a list of what you decided NOT to touch and why.

Work phase by phase, show me the diff of each one, and if anything puts the sacred rule at risk, STOP and ask me before continuing.
Why the prompt goes module by module
Notice that the prompt points at ONE file or folder, not the whole project. That's on purpose. One huge surgery all at once is impossible to review — the diff comes out with thousands of lines and you can't trust that a behavioral change didn't sneak in. Module by module, each operation is small, reviewable and reversible. Precise surgery, not demolition.

6. Verify the surgery didn't leave wounds

A surgery isn't over when you close up: it's over when you confirm the patient is fine. The sacred rule (zero behavioral changes) has to be checked, not just trusted. There are two automatic safety nets that confirm it for you in seconds, and that your agent can run without you programming anything.

terminal
# 1) The type check: zero errors = the surgery didn't break the contracts
npx tsc --noEmit

# 2) The tests: if they passed before and pass the same after,
#    behavior was preserved
npm test
The diff is your X-ray
Before accepting the surgery, look at its diff (the changes) in GitHub Desktop or with git diff. Reading rule: almost everything you see should be RED lines (deleted) or things moved around, not new logic. If you see user-facing text strings changed, different default values, or new conditions, there's a possible wound there — ask the AI why before accepting.

7. The easiest paths · what the AI does by chat and what you decide

So it doesn't get complicated: most of the surgery is done by your code agent alone, through the chat. Your job is to steer and approve. Here's the split.

What the AI does for you (through the chat)
Sweeping the module and detecting the dead code, the duplicates, the any and the badly built animations — you just give it the master prompt.
Applying the fixes phase by phase, showing you the diff of each one.
Running tsc and the tests to confirm it didn't break anything.
Writing the final health report with the counts and what it decided not to touch.
What YOU decide (on the web / with buttons)
Making the safety commit BEFORE — your undo button. You do that yourself from GitHub Desktop or the chat, before operating.
Approving the doubtful deletions — when the AI isn't sure whether something is used, it asks you; the final call is yours.
Reviewing the diff — reading the changes and confirming there are no behavioral wounds before accepting.
Deciding the scope — which module gets operated on and in what order. Don't delegate "operate on everything": go in parts.
In NeuralOS, this discipline comes built in
This way of working — building on one side and auditing/cleaning on another, in separate turns, without touching what already works — is the same philosophy NeuralOS is built with on the inside: every front gets raised and then put through an adversarial audit pass before it's called done. The vision you already see tangible in the interface — the chat that builds your app, the editors, the flow engine — leans on that habit of not letting the code rot. The core idea of the product is the same as this resource's: that building fast and building clean don't have to be enemies.
The C-A-R protocol · build without bugs
Surgery is first cousin to C-A-R: building and auditing in separate turns. This resource gives you the audit method that the discipline of cleaning without breaking is born from.
Save everything to GitHub before the AI breaks it
Your safety net before any surgery: the commit that lets you roll back with one click if a phase deletes something that was needed.
#code surgery#refactor#dead code#typescript#performance#advanced
Ready to build?

Start building in
under 3 minutes

Join 4,200+ builders. No credit card. Build your first app with AI in minutes.