Tinker AI
Read reviews
intermediate 9 min read

Aider for incremental refactoring: a terminal workflow that actually scales

Published 2026-05-05 by Owner

Aider is the odd one out among AI coding tools. It runs in your terminal, speaks git natively, and doesn’t require an IDE. Most developers overlook it because the setup is less polished than Cursor or Copilot. That’s a mistake for a specific use case: large, incremental refactors that touch many files.

This guide walks through the workflow I use when I need to change a pattern across a codebase — not a one-off function rewrite, but the kind of migration that takes a week and has to stay coherent across 50 commits.

Why Aider for refactoring specifically

IDE-based tools are optimized for the single-file edit loop: open file, get suggestion, accept, move on. That works well for feature development.

Refactoring is different. You’re changing the same pattern everywhere, and you need:

  • Confidence that every change follows the same rule
  • A clean commit history so you can bisect if something breaks
  • The ability to pause mid-refactor and pick it up tomorrow without losing context

Aider’s git integration handles all three. Every Aider change is a commit. You can git log the whole session, git revert any bad step, and continue the next day by showing Aider the same context files.

Setup

pip install aider-chat
export ANTHROPIC_API_KEY=...  # or OPENAI_API_KEY

Start in your repo root:

aider --model claude-3-5-sonnet-20241022

The --model flag matters. For refactoring work, I use Claude Sonnet because it follows complex instructions more precisely than GPT-4o — fewer cases where it changes the behavior while restructuring the shape.

The core workflow: context files + precise instruction

Aider reads whatever files you tell it to. The discipline is in being selective.

Don’t do this:

/add src/

Adding your whole src/ directory buries the model in irrelevant context. It will make changes based on the noisiest patterns in the files, not the ones you care about.

Do this instead:

For each step of the refactor:

  1. Add only the files relevant to this step
  2. Write a precise instruction that describes the before and after state
  3. Let Aider commit the change
  4. Review the diff with git show
  5. Add the next batch of files

Example session for migrating from a callback API to async/await:

/add src/lib/db.ts src/lib/api.ts

Then:

These two files use a callback pattern for async operations:
  query(sql, params, callback)

Migrate them to async/await. The new signature should be:
  async query(sql: string, params: unknown[]): Promise<QueryResult>

Do not change any callers — only the function definitions and their internal implementation.
Update the JSDoc comments to reflect the new signatures.

Aider will make the change and commit it. Run your tests:

bun run test src/lib/db.test.ts

If they pass, move to the callers:

/add src/services/user.ts src/services/order.ts
The query function in db.ts is now async. Update all callers in these files to use await instead of callbacks.

This step-by-step approach keeps each commit focused. You can tell exactly when and where something broke.

Using /read-only for reference files

Sometimes you need Aider to understand a type definition or interface without letting it modify that file. Use /read-only:

/read-only src/types/index.ts
/add src/lib/user.ts

Rewrite the user parsing logic to return User[] instead of any[]. The User type is defined in types/index.ts.

This is the equivalent of Cursor’s @ context — but you’re explicitly controlling what’s editable.

The commit discipline

Aider auto-commits by default. This is actually useful for refactoring, because it means every logical step is captured.

Don’t fight the auto-commits. At the end of the session, you can squash them if your team has a “one feature, one commit” convention:

git rebase -i origin/main

But during the refactor, the granular commits are your safety net.

When Aider makes a wrong change

If Aider misunderstands your intent and produces a wrong diff:

git revert HEAD

Then rewrite your instruction with more constraints. Don’t try to correct the wrong output in-session — revert cleanly and give a better prompt.

This is the same advice as Cursor, but with Aider you have the git plumbing to make it fast and clean.

What Aider can’t do well

Aider is not good for:

  • Visual iteration (no preview, no hover-to-inspect)
  • Code that requires understanding runtime behavior
  • Large single-file changes where you need to see the diff inline

For those, use Cursor. Aider’s strength is the git-native, multi-file, steady-progress workflow. If you’re doing a refactor that would otherwise take a week of careful manual find-and-replace, Aider can get you there in a day with a clean commit history to show for it.