“We might need it later. Should we build it in advance?”
This temptation comes up constantly in development. We add configuration options ahead of time, set up internationalization structures in advance, and even create tables so values can be changed from an admin panel.
YAGNI, the topic of today’s article, answers this temptation with a firm “No.” Along with KISS and DRY, it is often considered one of the three major development principles.
YAGNI stands for “You Aren’t Gonna Need It.” It means, “You probably won’t need that anyway.”
The term originated in the Extreme Programming (XP) methodology. It became a principle after people in the XP community, including Kent Beck and Ron Jeffries, used it so habitually.
The core argument is simple.
Implement a feature when it is actually needed—not when you predict that it might be needed.
What’s wrong with building things in advance?
The immediate counterargument is, “Wouldn’t it be more convenient later if we build it now?” The problem is that these predictions are usually wrong.
In an article Martin Fowler wrote on this topic, he divides the costs of building features in advance into four categories.
| Cost | Description |
|---|---|
| Implementation cost | The time spent building a feature that is not needed right now |
| Delay cost | The real feature that should have been built during that time gets delayed |
| Maintenance cost | Even unused code continues to require testing, refactoring, and bug fixes |
| Repair cost | By the time it is actually needed, the requirements have changed and the code must be reworked |
The last one hurts the most. When “later” really arrives, its requirements almost always look different from what I expected. In the end, you pay twice—including the cost of reworking code built in advance.
How YAGNI breaks down in real-world development
Everyone nods when you explain it, but in practice it slips in through situations like these.
1. Adding parameters in advance
// When there are only email notifications for now
func sendNotification(user: User, message: String, channel: String = "email",
retryCount: Int = 3, priority: String = "normal",
template: String? = nil) {
// channelcode that works only when "email"
}
Every call site uses only sendNotification(user: user, message: msg). The remaining parameters were created “for when we add Slack notifications later,” but that Slack notification requirement never arrived.
2. Adding a protocol in advance
Creating a protocol when there is only one implementation. It is the pattern of creating UserServiceProtocol together while making one UserService, but until a second implementation appears, the protocol is merely decoration that increases the file count.
3. “Wouldn’t it be nice to move it into configuration?”
Some teams move every value into configuration files and admin screens because hardcoding feels scary. In reality, those settings may never be changed even once a year, and as they grow, so do questions like, “What does changing this value affect?”
What YAGNI does not mean
To prevent misunderstandings, let’s draw the line. YAGNI does not mean the following.
First, it does not mean you should stop designing. Efforts that make code easier to change—good names, small functions, and tests—have immediate value and are not subject to YAGNI. In fact, code should be easy to change so you can build what is needed quickly when the time comes.
Nor does it mean postponing decisions that are difficult to reverse. For choices such as selecting a database or defining a public API specification, it is right to think ahead because changing them later is difficult. YAGNI targets features that could easily be added later but are built in advance anyway.
The criteria I use
When I wonder, “Should I build this in advance?” I ask two questions.
Is there evidence on the roadmap that this feature is needed, or does it exist only in my imagination?
Will adding it later be much more expensive than adding it now?
If the evidence exists only in my imagination and adding it later costs about the same, I do not build it. It turns out that most cases fall into this category.
Summary
There are three things to take away from YAGNI.
- Build features when they become necessary, not when they merely seem like they might be needed.
- Features built in advance charge you four times over: implementation, delay, maintenance, and repair.
- However, good design habits and difficult-to-reverse decisions are not YAGNI targets.
Put KISS, DRY, and YAGNI together, and the three principles converge on one sentence: Build what you need today, keep it simple, and build it in only one place.
If even one feature is lying dormant because you thought, “We might use it someday,” you may end up deleting it yourself two years from now.

