Always Be Refactoring
The Claim
Refactoring shouldn’t be a separate project. It should be continuous, baked into the way you work. Every time you touch code, you have a chance to leave it a little better than you found it. The “big rewrite later” is a fairy tale we tell ourselves so we can sleep at night. Small improvements now? Those actually happen.
Why I Think This
I’ve been promised so many big refactors that never materialised. I’ve lost count.
“We’ll clean this up after launch.” Launch happens. Clean-up doesnt.
“Next quarter, we’ll tackle the technical debt.” Next quarter arrives with its own fires to put out.
“We need a dedicated refactoring sprint.” The sprint gets cancelled because someone needs a dashboard urgently.
Meanwhile, the code gets worse. Each compromise compounds like interest on a credit card nobody’s paying off. The big rewrite becomes bigger, scarier, more expensive. Eventually someone does the maths and decides its cheaper to just live with the mess. And so the mess becomes permanent.

What actually works? Constant small refactors. Boring, unglamorous, relentless tidying.
The Boy Scout Rule. Leave code better than you found it. Every PR, a small improvement. Rename a confusing variable. Extract a method. Delete dead code. Over time, it accumulates into something genuinely meaningful.
Refactor in context. When you’re already changing a function, clean it up while you’re there. You already have the mental model loaded. You already understand what it does and why. The marginal cost of tidying is tiny compared to coming back later, rebuilding all that context from scratch, and then trying to improve it.
Test-supported changes. Good tests make refactoring safe. Without them, refactoring is gambling. You’re basically closing your eyes and hoping for the best. Build the tests first, then refactor with confidence.
Small, frequent commits. Refactoring mixed with feature changes is dangerous. Separate your commits: one for behaviour-preserving cleanup, one for the actual change. When something breaks (and it will), you’ll know exactly which commit caused it instead of untangling a Frankenstein PR that’s half feature and half refactor.

The big refactor is a fantasy. The constant small improvement is real. I’ve seen it work on every codebase I’ve been involved with, and I’ve never once seen the “big rewrite” actually play out the way anyone promised it would.
The Counterargument
Feature pressure is real. I’m not going to pretend it isn’t. If you’re always refactoring, you’re never shipping, and at some point someone with a spreadsheet is going to start asking uncomfortable questions. Sometimes you genuinely need to compromise now and pay later.
And refactoring requires skill. Inexperienced developers making “improvements” can absolutely make things worse. I’ve reviewed PRs where someone “cleaned up” a module and introduced three new bugs in the process. Sometimes the safest thing is to leave code alone until you properly understand it.
Where I Might Be Wrong
Maybe some codebases really do need the big rewrite. Sometimes the foundation is so broken that incremental improvement is like rearranging deck chairs on the Titanic. You can tidy all you like, but if the architecture is fundamentally wrong, small changes won’t save you.
And churn is costly. Constant refactoring means constant merge conflicts, constant relearning, constant “why did this change?” in code review. Stability has value too. There’s something to be said for code that just sits there, doing its job, not being touched every other sprint.

The Takeaway
Build refactoring into your workflow. Make it habitual, not heroic.
- Every PR: One small improvement beyond the feature.
- Every bug fix: Clean up the surrounding code while you’re in there.
- Every code review: Suggest one refactoring.
The goal isnt perfection. It’s just not letting things get worse. That’s a low bar, and it’s amazing how few teams actually clear it.

The cleanest codebases I’ve ever worked on didn’t have dedicated refactoring sprints. They just had developers who tidied up after themselves, one commit at a time. Turns out that’s all it takes.