Skip to Content
All posts

The Fallacy of 'Future-Proofing' Code

 — #Software Architecture#Best Practices#Developer Habits#Overengineering

"Let's make this feature abstract. We'll probably need to support three other types of users in the future."

I have said this. You have said this. We have all said this.

And almost every single time, we were wrong.

The desire to "future-proof" code is deeply ingrained in software engineering. We want to be proactive. We want to show foresight. We want to avoid rewriting our code six months from now.

But in our attempt to predict the future, we usually just make the present unbearable.

The Cost of YAGNI Violations

YAGNI stands for "You Aren't Gonna Need It." It is the most frequently ignored principle in programming.

When you future-proof code, you are making a bet. You are betting that you know exactly how the business requirements will evolve.

If you guess right, you save a little bit of refactoring time.

If you guess wrong (and you usually will), you pay a massive penalty:

  1. You built the wrong abstraction. The new requirements don't quite fit the generic interface you designed, so now you have to hack around your own architecture.
  2. You added unnecessary cognitive load. Every developer who touches that code has to understand an abstraction that isn't actually being used yet.
  3. You wasted time. Time spent building hypothetical features is time not spent shipping actual value.

The "Delete-ability" Metric

Instead of optimizing for "how easy is this to extend," we should be optimizing for "how easy is this to delete."

Highly abstracted, heavily coupled, future-proofed code is notoriously difficult to delete because its tentacles reach everywhere.

Simple, concrete, slightly repetitive code is incredibly easy to delete. If a feature fails and the business decides to pivot, you just highlight the block and press Backspace.

Design for the Present, Refactor for the Future

The best way to prepare for the future is to write clean, simple code for the present.

When the future actually arrives—when the product manager asks for that second type of user—that is when you refactor. You now have concrete requirements. You aren't guessing anymore. You can build the exact abstraction needed to solve the actual problem in front of you.

Stop trying to predict the future. Your crystal ball is broken. Write code for today.