How to Make Major Code Refactors in the Cursor

historically it was a tedious yet important task. Refactoring is the act of taking a piece of code and cleaning it up, by better separating things of concern, the Do Not Repeat (DRY) principle, or other code hygiene principles.
Code filters have always been important, but with the release of coding agents, we are seeing higher coding results, which inevitably leads to more need to recode. I often find myself in a situation where some code needs to be redone, although I don't think this is a warning sign, considering the amount of code I release is also much higher now with the help of LLMs.
Fortunately, the effort to code has decreased significantly since the release of LLMs.
In this article, I'll go through my top code refactoring method using scripting agents like Cursor or Claude's Code. I will include my general method and thought process, so the model you use doesn't matter.
Why should you recode?
You should recode whenever you notice too many antipatterns in your code, or when you realize that you (or your coding agent) are spending more time than necessary on implementation. Your threshold before doing a refactoring should be lower than it was before the release of LLMs, considering that refactors are easier and faster to implement now using coding agents.
That's because part of the training set for coding agents is to recode, and they're pretty good at it. In most cases, I'd say they're better than humans, considering that refactoring requires a lot of working memory:
- Remembering all the variables
- Input/output validation after refactor is the same as before refactor
- What files should be moved, deleted, and added
So, you should do code refactoring where:
- You or your coding agent finds many antipatterns in your code
- Initialization takes longer than it should (sign of bad code)
And you should do code refactorings because:
- Increase the speed of replication
- They are cheaper compared to LLMs
My approach is to refactor the code
In this section, I'll cover my high-level approach to code refactoring. I will go through four steps:
- Detects when to redo
- What to consider before refactoring
- What you should consider when refactoring
- What to consider after a refactor
This will highlight how you can approach refactoring, in general terms so you can replicate the processing yourself in your codebase.
1. Figuring out when to redo
The first step is to always find out if you should decide to refactor your code. There is usually no clear line on when to redo or not, and it takes some instinct to know when is a good time.
However, you should use simple general principles. If you see multiple antipatterns in the code, for example, with:
- Multiple duplicate code
- Missing docstrings and function types
- Misclassification of concerns
You should consider redoing it.
Also, if you see your coding agent spending longer than usual reading your codebase, trying to understand it. Or it struggles too much to do something, and errors appear elsewhere. You should also consider repurposing.
However, getting this instinct takes time, and in the beginning, you can try to refactor sooner rather than later (assuming refactoring is cheaper with LLMs), then adjust when you learn more along the way.
2. What should be considered before refactoring
Once you've reached this step, you've decided that some part of the codebase needs to be redone. Now you need to plan what scope the refactoring should cover, because naturally you should reduce the scope of the refactoring as much as possible.
Reduce the scope of rework as much as possible
Then I start planning, which I do mainly in two ways:
- (optional) If I want to discuss general architectural decision-making or high-level ideas, I start the conversation with Gemini on the console. I explain my situation, trade-offs, different solutions I am considering, and all other important information. I then had a conversation with Gemini about the decision. Note the word expression. I don't just ask Gemini a question about how to solve my problem; I discuss with the model what is the best way, and I try to understand the issue as best as possible.
- Every time I start using editing mode in Cursor or Claude's Code, where you tell the model what you want to do, it looks at your code base, and comes up with a strategy on how to implement a solution in your code base. Sometimes, I copy my dialogue from Gemini (if I've done that), and sometimes I just start my rework in Cursor.
Planning your route is very important, as you become aware of some issues you didn't know about before, and you can make decisions with as much information as possible. In addition, you can learn about the Cursor program, and modify it if needed. Most importantly, however, I recommend that you have a conversation with your coding agent about how to refactor it, instead of just asking them a simple question and getting only one answer.
You have to strive to have it discussions and your agents, and not just one question and answer
I recommend spending at least 10-15 minutes on this discussion when doing a major overhaul.
After the plan is made, I move on to step 3.
"""
Example plan.md file after using plan mode
In this scenario, the context is refactoring a messy, monolithic `server.js` (Express node app) into a cleaner MVC (Model-View-Controller) architecture with TypeScript.
"""
***
# Plan: Refactor Monolithic Server to MVC Architecture
## Context
Currently, `src/server.js` contains all database connections, route definitions, and business logic in a single file. We need to refactor this into a modular structure using TypeScript, splitting concerns into Controllers, Services, and Routes.
## User Requirements
1. Convert the project to **TypeScript**.
2. Extract database logic into a Singleton/Service.
3. Separate routes into `src/routes`.
4. Move business logic to `src/controllers`.
## Proposed File Structure
* `src/app.ts` (Entry point)
* `src/config/database.ts` (DB connection)
* `src/routes/userRoutes.ts` (Route definitions)
* `src/controllers/userController.ts` (Request handling)
* `src/services/userService.ts` (Business logic)
---
## Step-by-Step Plan
### Phase 1: Setup & Configuration
- [ ] Initialize TypeScript configuration (`tsconfig.json`).
- [ ] Install necessary `@types` dev dependencies (`node`, `express`).
- [ ] Rename `server.js` to `server.ts` temporarily to resolve immediate linting errors.
### Phase 2: Database Layer
- [ ] Create `src/config/database.ts`.
- [ ] Move the MongoDB connection string and connection logic from `server.ts` to `src/config/database.ts`.
- [ ] Ensure the database connection exports a robust singleton or connection function.
### Phase 3: Service & Controller Extraction
- [ ] Create `src/services/userService.ts`.
- [ ] Move raw database queries (find, create, update) here.
- [ ] Define interfaces for User data.
- [ ] Create `src/controllers/userController.ts`.
- [ ] Implement `getUsers`, `createUser`, and `updateUser` methods.
- [ ] Import `userService` to handle the logic.
- [ ] Ensure proper type typing for `Request` and `Response`.
### Phase 4: Routing
- [ ] Create `src/routes/userRoutes.ts`.
- [ ] Setup `express.Router()`.
- [ ] Map endpoints (`/users`, `/users/:id`) to the specific Controller methods.
### Phase 5: Entry Point Cleanup
- [ ] Create `src/app.ts`.
- [ ] Initialize the Express app.
- [ ] Import and apply middleware (CORS, JSON body parser).
- [ ] Mount `userRoutes`.
- [ ] Connect to the database using `src/config/database.ts`.
- [ ] Delete the original `src/server.js`.
### Phase 6: Verification
- [ ] specific verification step: Start the server using `ts-node src/app.ts` to ensure no runtime errors.
- [ ] specific verification step: Test the `/users` endpoint to ensure data flow is intact.
---
### Would you like me to create this file structure for you now, or start specifically with Phase 1?
3. What should be considered during the refactor
If you've reached this step, you've already prepared a good plan with your coding agent, and you've started refactoring. To make the refactor work well and make sure it works as well as possible, I keep these things in mind:
- Be as patient as possible with permissions. Of course, be aware of damaging commands, but having an agent that can execute multiple commands speeds up the process.
- Using Claude. My experience is that Claude Sonnet/Opus 4.5 is the best and fastest code model out there.
- Tell the agent to run test scripts if needed. Sometimes agents just try to debug the code on their own, but it's usually better to inform them to create a test script where they can see the input and output.
Then I let the Encoding Agent run until it finishes, which can take anywhere from a minute to 20 minutes. If it's one of the first times you use the code in the repo, you may have to allow a list of other commands, but as said, I'm trying to be gentle here, especially when we're talking about readable commands, which won't cause any damage.
I also allow my agent to create test scripts and run them at will, so that they can not only debug the code, but also see the input and output.
With this setup, I have the most success with a refactor with at most a few commands back and forth, and in most cases just one prompt.
4. What should be considered after the refactor
After the refactoring is done, you need to consider the changes. Sometimes you have to look at all the code carefully, although sometimes it's not necessary. However, I have some recommendations after the refactor is done:
- Ask the model to compare the input and output before the refactor (point the model to your master or dev branch, or whatever branch you branch from when you start a new branch). The model will give you an overview, and you usually have to make sure that the input and output are the same before and after. This tip has saved me a lot of bugs
- Perform a code review with a different agent (start with a new context), making it easier to identify errors that your agent didn't see when it was redoing.
- Ask Cursor to give you a thoughtful commitment message, and create PR for you. This both speeds up the process of getting the code into production, and makes your PR more descriptive
In particular, my first point in comparing the master/dev branch is important. Having the model compare the input and output to the previous code and the current code revealed so many bugs that the model didn't see during refactoring.
I believe that with even better code models, we will see fewer and fewer of these errors, although for now, I think it is important to have a model in the second review of the changes, both by comparing the input and output, and by conducting a code review.
The conclusion
In this article, I gave a high-level overview of how to refactor codes. I first discussed how to know when a refactor is needed, before going into detailing how to refactor. Then I put together how I use edit mode before recompiling, enable list commands during recompilation, and ask the model to do a second review of the recompiled code, with a refreshed context window.
I believe that the LLM redesign will be very important as we see higher and higher coding output, thanks to the LLM writing agents. And I believe that refactoring with LLMs is very effective, and something that everyone should keep in mind, especially when coding a lot using coding agents.
👉 My Free eBook and Webinar:
🚀 10x Your Engineering with LLMs (Free 3-Day Email Course)
📚 Get my free ebook Vision Language Models
💻 My webinar on Vision Language Models
👉 Find me on social media:
💌 Stack
🐦 X / Twitter



