Software Design

YAGNI in Summary: Why a Developer’s “We Might Use It Someday” Gets Expensive

“We might need it later. Should we build it in advance?”

4 min read
Cover image for YAGNI in Summary: Why a Developer’s “We Might Use It Someday” Gets Expensive

“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?”

Unused options still incur maintenance costs
Unused options still incur maintenance costs

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.

Two questions are usually enough to make the decision
Two questions are usually enough to make the decision
It is not too late to build it on the day it becomes necessary
It is not too late to build it on the day it becomes necessary

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.