Dead Code and Duplication: Keeping an AI-Built Codebase Clean
AI-assisted codebases don't rot the way hand-written ones do. They bloat. Every regeneration writes new code without reliably removing the old, and after a few weeks you have functions nothing calls, three helpers that format the same date, and two versions of the same logic — one of which still has the bug you fixed in the other.
Why it happens structurally
A model regenerating a feature doesn't know what the last version left behind; it just writes a complete new answer. The old event handler, the old utility, the old styles — unless they conflict loudly, they stay. And because models err toward self-contained output, they'd often rather write a fresh formatDate() than hunt for yours. Multiply by every iteration session and duplication becomes the codebase's natural state.
Why it actually matters
This isn't tidiness for its own sake. Duplication means a fix applied to one copy silently misses the others — the classic "I fixed that yesterday, why is it still happening?" Dead code means every future regeneration carries irrelevant context, confusing both you and the model you paste it into. Bloat also makes review slower exactly where vibe coding needs review to be fast.
The pruning routine
- Hunt duplicates by concept, not by name. Search for the problem — "date", "format", "validate", "fetch" — and see how many implementations you find. Pick the best one, point everything at it, delete the rest.
- Find the orphans. For each function or file you suspect, search for its name project-wide. One hit (its own definition) means nothing calls it. Confirm, then delete.
- Delete, don't comment out. Commented-out blocks are dead code with extra steps — they still mislead readers and models. If you might want it back, that's what version control (or a dated backup copy) is for.
- Verify by behavior after each removal. Run the app and click through the affected flows. Dead code should remove silently; if something breaks, it wasn't dead — good to know now.
- Prune after milestones, not daily. Mid-iteration cleanup fights the churn. Clean once a feature settles.
Prevention costs one sentence
When regenerating, add: "Replace the previous version of this feature and remove any code that becomes unused." Models are decent at cleanup when explicitly asked and near-certain to skip it when not. Similarly, "use the existing helper functions where possible — here they are" heads off the fourth date formatter before it exists.
The payoff compounds
A lean codebase reviews faster, regenerates better (less noise in the context you provide), and debugs honestly — one implementation means one place to fix. Ten minutes of pruning per milestone is the cheapest performance upgrade your workflow can buy.