Cleaning Up Your Code After Launch — How to Refactor with AI
Learn how to handle the refactoring that every vibe-coded project eventually needs, working alongside AI.
Once you launch your service, you hit a fork in the road: keep adding new features, or take a moment to clean up the code you’ve built so far.
For a vibe coding project where you’ve been building fast, this moment matters. If you keep piling on features without ever cleaning up, eventually even the AI will have trouble making sense of your codebase. In this post, we’ll cover how to read and clean up your code together with AI — in other words, refactoring.
Why cleanup is essential after vibe coding
Refactoring is the work of improving your code’s structure without changing its behavior. There’s no visible change to the user, but it makes future edits and extensions much easier.
Code that’s been built quickly through vibe coding tends to develop a common set of problems.
| Problem | Example | Impact |
|---|---|---|
| One file doing too many jobs | App.jsx handles UI + logic + data processing all at once | Hard to figure out where to make a fix |
| Duplicate code | Similar functions exist in 2-3 different places | Fixing one means you have to manually update the others |
| Inconsistent naming | getBookmarks, fetchData, loadItems all do the same thing | Takes longer to read and understand the code |
| Hardcoded values | Strings like localStorage.getItem('bm-data-v1') scattered in multiple places | Renaming a key means hunting down every occurrence |
None of these problems are noticeable while you’re quickly adding features, but as the code piles up, adding new features or fixing bugs starts taking longer and longer.
How to read and improve your code’s structure with AI
To refactor on your own, you need to understand the code first. But since your vibe-coded code was written by AI, it can be hard to know exactly what lives where.
This is another place where you lean on AI. Here’s a good prompting approach for refactoring requests.
Step 1: Ask for an analysis of the current code
Read through the current bookmark-app project's code and tell me:
1. What role each file plays
2. Where any single file is doing too many jobs
3. Where there's duplicated logic
4. The top 3 things worth improving
Don't make any changes yet — just analyze.
Asking for analysis first matters. If you jump straight to “fix it,” the AI might change far too much at once.
Step 2: Set priorities
Once the AI shares its analysis, decide what order to tackle things in. Don’t try to fix everything at once.
From the analysis above, let's start with item 3 (separating out the localStorage logic).
Move the localStorage-related code currently in App.jsx into a storage.js file.
Keep the functionality exactly the same — just change the structure.
Step 3: Verify it still works after the change
After changing the code, always check in the browser that the feature still works the same way. Refactoring is supposed to leave functionality untouched, but mistakes can still happen.
Step 4: Move on to the next item
Once you’ve verified it, move on to the next item. One thing at a time.
Prompt patterns you’ll use often when refactoring
Splitting out a component
In App.jsx, split out the part that displays the bookmark list into a BookmarkList.jsx component.
Also handle wiring up the props and callback functions.
Extracting shared logic
The functions fetchBookmarks(), saveBookmark(), and deleteBookmark() are scattered across different files.
Combine them into a custom hook at hooks/useBookmarks.js.
Cleaning up constants
Collect the values hardcoded as strings in the code (like localStorage key names)
into a constants.js file.
Removing unnecessary code
Clean up commented-out code, unused imports, and unfinished functions.
Only remove things that won't affect functionality.
Reflecting the refactoring results in CLAUDE.md
Refactoring changes structure rather than adding new features, so the CLAUDE.md that describes your structure needs to be updated to match too.
The refactoring is done. Update the structure notes in CLAUDE.md as follows:
- Added storage.js (handles localStorage logic)
- Added hooks/useBookmarks.js (bookmark CRUD logic)
- App.jsx now handles UI layout only
- The loadData() function was removed
When your docs stay in sync with the code, later on you can just ask the AI “what does the current structure look like?” and get an accurate picture of the current state right away.
When to stop refactoring
Refactoring never really ends. There’s always more you could improve. But you can’t spend all your time refactoring while you’re also trying to run a live service.
Here are the signs that it’s fine to stop refactoring and move on to the next feature:
- When you ask the AI for a new feature, it gets added cleanly without conflicting with the existing code
- When you need to fix something, you can immediately tell which file to open
- Each code file is roughly 200 lines or less
Perfectly tidy code isn’t the goal. The goal is a state where adding the next feature or fixing a bug doesn’t feel like a hassle.
Next time
In the next post, we’ll cover something you’re bound to run into after launch: production bugs. Bugs that show up in the environment real users are actually using behave differently from what you see in local development. We’ll look at how to track down the cause and fix it together with AI.