Quality & Team

Refactoring

Foundational

Refactoring improves the structure of code without changing what it does. You make it clearer, simpler, and easier to change, while the behaviour stays exactly the same. Done in small steps and protected by tests, it keeps a codebase healthy. Done as a large, risky rewrite, or mixed into feature changes, it causes outages and diffs nobody can review.

The key idea, especially for newer engineers: refactoring must not change behaviour. If behaviour changes, that is a feature or a fix, not a refactor. Mixing the two makes both impossible to review and dangerous to ship. Tests are what make refactoring safe. They prove the behaviour stayed the same.

Healthy teams refactor a little, often, improving code as they work in it, rather than letting it decay until only a frightening rewrite will do. This is how technical debt gets paid down in practice (see Technical Debt).

Refactor safely

Keep it reviewable and bounded

Refactor and feature in one PR // one 900-line PR: renames everything, restructures 5 files,
// AND changes the screening threshold from 80 to 70

Nobody can tell the safe renames from the real behaviour change hidden among them. The threshold change, a real risk decision, ships unreviewed inside the refactoring noise.

Separate, tested, small PR 1: extract + rename (no behaviour change; tests still green)
PR 2: change screening threshold 80 -> 70 (reviewed on its own, with rationale)

Each PR is easy to review. One proves the change is structure-only; the other puts the real decision under proper review.

Self-review checklist

Why it matters: Continuous, safe refactoring keeps a codebase easy to change, instead of slowly turning into something everyone is afraid to touch. Keeping behaviour identical, relying on tests, and separating refactors from feature changes lets us improve the code all the time, without the outages and unreviewable diffs that give refactoring a bad name.