You Aren't Gonna Need It
Concept
The principle that a probable future need is not a reason to build something; you build it once the need is real.
Why it exists
The idea that building ahead makes life easier later is a natural one. Even when only one case is needed now, designing to accept several means less work when the next request arrives. That is why designing for extension gets used as praise rather than as a warning.
Pagedeck made that call once. While building email notifications, the team decided other channels would follow and built a structure where the channel could be swapped out. It took three extra weeks, which nobody objected to at the time.
No channel was added for the next eighteen months. And on the day another channel was finally chosen, the structure did not fit. The channel imagined in advance sent in one shot like email; the channel that turned out to be needed held a separate connection per person and had to retry on failure. The three weeks of structure came out and got rewritten from scratch.
The cost of building ahead was not only the time to build it. For those eighteen months, everyone who read that code read an unused branch along with it, and a wrong assumption had hardened into structure that got in the way when the real requirement arrived.
How it works
There is one test: is it used now. Something scheduled for next week is still not built now.
The case rests on there being three costs attached to building early.
- The time to build. The most visible cost and in practice the smallest.
- The cost of reading and maintaining. An unused branch still gets read while it sits in the code, still gets considered when something nearby changes, and still runs in the test suite. That cost is charged every month until the code is deleted.
- The cost of a hardened wrong assumption. The largest of the three. When the real requirement arrives differently from the guess, the structure built in advance obstructs it. Building from nothing beats building while correcting a wrong structure, and the difference is usually larger than the original estimate.
It is not a rule to defer everything. The dividing line is what the change costs later. A screen layout or a single function can wait, because changing it when needed is cheap. Three things do not wait: how data is stored, any specification published externally, and permissions and security. Changing a storage structure after data accumulates means migrating what accumulated, and changing a published specification stops everyone already integrated, neither of which is a change you can make on a Tuesday afternoon.
The principle also has a precondition: building it later has to be easy. With tests in place and units kept small, adding the thing on the day it is needed takes three days; without that, it takes three weeks. So this sits at the opposite end from an excuse to write careless code. Not building now requires staying in a state where building later is possible, which is ongoing work rather than a decision.
Building every case and leaving one extension point are also different things. The first is what this principle blocks; the second is usually cheap enough to include. Making one function swappable takes an hour; building three channels takes three weeks. The cost ratio is the whole argument.
Where it shows up
The most frequent setting is a design discussion. When someone proposes building to accept several cases later, the question is where those several cases are right now. A customer request in writing, an item on the roadmap, or a hunch — the answer differs by which, and only the first two justify code today.
The second is code review, where a colleague reads a change before it merges. An abstraction used in exactly one place, a setting with exactly one value, an option nobody calls. Whether an unused branch arrived becomes a checklist item, and it is one of the easier things to spot in a diff.
The third is writing requirements. It pairs with the out of scope column that records what is deliberately not being done this time. Something excluded in the document existing as structure in the code is more common than it sounds; the two drift apart quietly.
The fourth is configuration. Decisions to expose a value as a setting "so it can be changed later" accumulate into twenty settings, half of which nobody has ever changed while they multiply the combinations. One setting doubles the number of cases that have to be tested, and nothing removes it once it is documented.
The fifth is narrowing what gets built. Defining an MVP, the smallest product that can test a hypothesis, points the same direction — one applies to product scope and the other to code structure, and both answer the same question about what can wait.
How it sounds at work
"Isn't that a YAGNI? We only have one channel right now."
Do not build a branch nothing uses.
"Let's settle the data structure up front. This one is expensive to change later."
Items costly to reverse are the exception.
"Hardcode the value instead of making it a setting. Nobody's going to change it."
Choosing present simplicity over future flexibility.
At Pagedeck, Theo puts one line in every design document: what is not being built, and why. When the same discussion reopens later, that line means starting from whether the judgment still holds rather than from the beginning.
Deleting what was built ahead falls under the same principle. A branch unused for six months goes onto the technical debt list and comes out. Deleting is an easier judgment than building, because the absence of any usage record is the evidence, and nobody has to predict anything.
What people get wrong
Reading it as an argument against planning is the most common mistake. Not building in advance sounds like not thinking in advance. But what the principle governs is the moment of building. Anticipating which requirements may come and encoding them now are different acts. Anticipate, keep a structure that makes the anticipated thing easy to attach, and do not build it until the requirement is real. Doing all three at once is what this looks like in practice.
The second is treating it as a rule with no exceptions. The name is emphatic, so it reads that way. But some deferrals are cheap and others are not. Changing a storage structure later means migrating the accumulated data while people are using the product, which turns into a multi-day plan. A team that applies this without exception spends those days six months in, usually during the quarter it could least afford them.
Easily confused with
| Term | What it prevents | How it differs |
|---|---|---|
| DRY | The same knowledge duplicated in several places | Cleans up what already exists. YAGNI says not to build what does not exist yet, so applying both filters out inventing shared structure nothing uses |
Where to go next
- Code Quality
see which family this principle belongs to
- DRY
the principle in the same family facing the other direction
Last updated 2026-09-16