Code YAGNI
"Should I Build This?" Decision Table
| Evidence |
Build It |
Don't Build It |
| Concrete user request with measured demand |
Yes |
— |
| Speculative ("we might need it") |
— |
Wait for evidence |
| One stakeholder's opinion, no data |
— |
Validate first |
| Enables a committed near-term deliverable |
Yes |
— |
| "While we're at it" during adjacent work |
— |
Separate ticket; evaluate independently |
| Framework/library code (multiple consumers) |
Yes (interfaces expected) |
— |
Four Costs of Presumptive Features
| Cost |
What It Means |
Why It Matters |
| Build |
Time and effort to implement now |
Diverts resources from confirmed requirements |
| Delay |
Opportunity cost — what else could ship instead |
Features have time value; delay erodes ROI |
| Carry |
Ongoing maintenance, testing, documentation |
Every feature is a liability until proven valuable |
| Repair |
Refactoring when assumptions prove wrong |
Wrong abstractions are harder to fix than missing ones |
Statistical Case Against Speculation
At Microsoft, Kohavi et al. found:
- ~1/3 of features succeeded in improving their target metric
- ~1/3 had neutral results (no measurable impact)
- ~1/3 actually hurt the metric they were designed to improve
Similar results at Amazon, Netflix, and other companies with rigorous A/B testing. The default assumption should be that a feature will fail to deliver value until measured otherwise.
Speculative Generality Detection Signals
| Signal |
What It Looks Like |
Action |
| Single-implementation interface |
IFooService with only FooServiceImpl |
Inline; extract interface when second impl arrives |
| Unused extension points |
Plugin registry with one plugin |
Remove the registry; add when needed |
| Test-only consumers |
Code used only in tests, not production |
Likely dead; verify and remove |
| One-type factory |
Factory that only creates one type |
Replace with direct construction |
| Unused parameters |
Parameters passed but never read |
Delete (Try Delete Then Compile) |
| Unnecessary delegation |
Wrapper that just calls through |
Inline the wrapper |
| Future-oriented naming |
V2, New, Enhanced prefix/suffix |
Rename to describe current behavior |
Build-vs-Not-Build Decision Framework
Step 1: Requirement Concreteness
├── Concrete (user stories, measured demand, committed deliverable)
│ → Proceed to Step 2
├── Speculative ("might need", "just in case", single opinion)
│ → STOP. Don't build. Revisit when evidence appears.
└── No identified users
→ STOP. Apply YAGNI.
Step 2: Cost of Deferral
├── High (security, data integrity, architectural foundation)
│ → Build now — deferral creates larger problems
├── Medium (performance, UX polish)
│ → Build if within current sprint scope; otherwise defer
└── Low (convenience features, edge cases)
→ Defer — build when concrete demand materializes
Step 3: Codebase Malleability
├── Easy to add later (modular, well-tested, clean interfaces)
│ → Defer — you can add it cheaply when needed
└── Hard to add later (tightly coupled, no tests, deep integration)
→ Consider building now if Steps 1-2 support it
"Is This YAGNI or Good Design?"
| Situation |
YAGNI (Don't Build) |
Good Design (Do Build) |
| Interface with no second implementation |
YAGNI — inline it |
Good design if needed for testing now |
| Error handling for unlikely scenario |
YAGNI if truly unlikely |
Good design if failure is catastrophic |
| Configuration for values that never change |
YAGNI — hardcode it |
Good design if ops needs runtime control |
| Abstraction over a single dependency |
YAGNI if dependency is stable |
Good design if dependency may change |
| Performance optimization |
YAGNI without profiling data |
Good design if measured hot path |
"How Likely Is This Feature to Succeed?"
| Evidence Level |
Estimated Success Rate |
Action |
| A/B tested with positive results |
~70-80% |
Build with confidence |
| Requested by multiple users with data |
~50-60% |
Build, but measure |
| Requested by one stakeholder |
~30-40% |
Prototype first, validate |
| "We think users will want this" |
~15-25% |
Don't build; gather evidence |
| "We might need this someday" |
<10% |
YAGNI — park it |
Checklists
Planning Phase YAGNI Check
Code Review YAGNI Check
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: code-yagni3description: YAGNI decision frameworks for evaluating whether to build a feature, detecting speculative generality, and preventing unnecessary feature bloat. Use when planning involves new features, design decisions, or "should we build this" questions during brainstorm, scope, or architecture review. Covers four costs of presumptive features, build-vs-not-build decision framework, speculative generality detection, and bloat antipatterns. Use when this capability is needed.4---56# Code YAGNI78## "Should I Build This?" Decision Table910| Evidence | Build It | Don't Build It |11|----------|----------|----------------|12| Concrete user request with measured demand | Yes | — |13| Speculative ("we might need it") | — | Wait for evidence |14| One stakeholder's opinion, no data | — | Validate first |15| Enables a committed near-term deliverable | Yes | — |16| "While we're at it" during adjacent work | — | Separate ticket; evaluate independently |17| Framework/library code (multiple consumers) | Yes (interfaces expected) | — |1819## Four Costs of Presumptive Features2021| Cost | What It Means | Why It Matters |22|------|--------------|---------------|23| **Build** | Time and effort to implement now | Diverts resources from confirmed requirements |24| **Delay** | Opportunity cost — what else could ship instead | Features have time value; delay erodes ROI |25| **Carry** | Ongoing maintenance, testing, documentation | Every feature is a liability until proven valuable |26| **Repair** | Refactoring when assumptions prove wrong | Wrong abstractions are harder to fix than missing ones |2728## Statistical Case Against Speculation2930At Microsoft, Kohavi et al. found:31- **~1/3** of features succeeded in improving their target metric32- **~1/3** had neutral results (no measurable impact)33- **~1/3** actually *hurt* the metric they were designed to improve3435Similar results at Amazon, Netflix, and other companies with rigorous A/B testing. **The default assumption should be that a feature will fail to deliver value until measured otherwise.**3637## Speculative Generality Detection Signals3839| Signal | What It Looks Like | Action |40|--------|-------------------|--------|41| Single-implementation interface | `IFooService` with only `FooServiceImpl` | Inline; extract interface when second impl arrives |42| Unused extension points | Plugin registry with one plugin | Remove the registry; add when needed |43| Test-only consumers | Code used only in tests, not production | Likely dead; verify and remove |44| One-type factory | Factory that only creates one type | Replace with direct construction |45| Unused parameters | Parameters passed but never read | Delete (Try Delete Then Compile) |46| Unnecessary delegation | Wrapper that just calls through | Inline the wrapper |47| Future-oriented naming | `V2`, `New`, `Enhanced` prefix/suffix | Rename to describe current behavior |4849## Build-vs-Not-Build Decision Framework5051```52Step 1: Requirement Concreteness53├── Concrete (user stories, measured demand, committed deliverable)54│ → Proceed to Step 255├── Speculative ("might need", "just in case", single opinion)56│ → STOP. Don't build. Revisit when evidence appears.57└── No identified users58 → STOP. Apply YAGNI.5960Step 2: Cost of Deferral61├── High (security, data integrity, architectural foundation)62│ → Build now — deferral creates larger problems63├── Medium (performance, UX polish)64│ → Build if within current sprint scope; otherwise defer65└── Low (convenience features, edge cases)66 → Defer — build when concrete demand materializes6768Step 3: Codebase Malleability69├── Easy to add later (modular, well-tested, clean interfaces)70│ → Defer — you can add it cheaply when needed71└── Hard to add later (tightly coupled, no tests, deep integration)72 → Consider building now if Steps 1-2 support it73```7475## "Is This YAGNI or Good Design?"7677| Situation | YAGNI (Don't Build) | Good Design (Do Build) |78|-----------|---------------------|----------------------|79| Interface with no second implementation | YAGNI — inline it | Good design if needed for testing now |80| Error handling for unlikely scenario | YAGNI if truly unlikely | Good design if failure is catastrophic |81| Configuration for values that never change | YAGNI — hardcode it | Good design if ops needs runtime control |82| Abstraction over a single dependency | YAGNI if dependency is stable | Good design if dependency may change |83| Performance optimization | YAGNI without profiling data | Good design if measured hot path |8485## "How Likely Is This Feature to Succeed?"8687| Evidence Level | Estimated Success Rate | Action |88|----------------|----------------------|--------|89| A/B tested with positive results | ~70-80% | Build with confidence |90| Requested by multiple users with data | ~50-60% | Build, but measure |91| Requested by one stakeholder | ~30-40% | Prototype first, validate |92| "We think users will want this" | ~15-25% | Don't build; gather evidence |93| "We might need this someday" | <10% | YAGNI — park it |9495## Checklists9697### Planning Phase YAGNI Check9899- [ ] Every feature has an identified user or measured demand100- [ ] No "just in case" abstractions without a second use case101- [ ] Deferred items are explicitly listed with revisit criteria102- [ ] Build-vs-not-build decision is documented for non-obvious choices103104### Code Review YAGNI Check105106- [ ] No single-implementation interfaces (unless needed for testing)107- [ ] No unused parameters or extension points108- [ ] No future-oriented naming (`V2`, `New`, `Enhanced`)109- [ ] No factory/registry patterns with a single consumer110111---112> Converted and distributed by [TomeVault](https://tomevault.io/claim/smileynet) — claim your Tome and manage your conversions.113<!-- tomevault:4.0:skill_md:2026-04-14 -->