<arch.design/>
Principles/YAGNI — You Aren't Gonna Need It
{ }CodeArchitecturebeginner1999generalxpextreme-programmingspeculative-generality

YAGNI — You Aren't Gonna Need It

Don't implement something until you actually need it — speculative features add complexity today and may never deliver value.

4/5
{ }
Operates at: Code level

Inside a codebase — classes, modules, files

How it works

YAGNI is an Extreme Programming (XP) principle, coined by Ron Jeffries around 1999. The rule: don't add functionality until it is genuinely needed for a current requirement.

The temptation to violate YAGNI is strong and feels responsible: 'I'll add a plugin system now so we're ready when we need it', 'I'll make this configurable so any team can use it', 'I'll build the abstraction now before the second use case arrives'. These all seem like good engineering. They are, in fact, speculation — you're paying a real cost today (complexity, maintenance, documentation, testing) for a hypothetical future benefit.

The problem is that the future rarely looks like you predicted. The plugin system you built handles the wrong plugin model. The configurability makes the simple case harder. The abstraction has the wrong seams for the second use case that actually arrives.

XP's answer: build exactly what the current user story needs. When the second use case arrives, refactor with full knowledge of both. The result is almost always a better abstraction than the one guessed in advance — and you only pay for it when you actually need it.

Implementation

TypeScript · Go · Rust
// ❌ Speculative — building a plugin system "we might need later"
interface FormatterPlugin { transform(text: string): string; }

class TextFormatter {
  private plugins: FormatterPlugin[] = [];
  registerPlugin(p: FormatterPlugin) { this.plugins.push(p); }
  format(text: string): string {
    return this.plugins.reduce((t, p) => p.transform(t), text);
  }
}
// Spent two days building this. Plugins: 0. Users who asked for it: 0.

// ✓ Build what you need now; refactor when the second use case arrives
function formatText(text: string): string {
  return text.trim().replace(/\s+/g, " ");
}

// When a real second use case arrives, you'll know exactly what the
// abstraction should look like — and you'll build it with full knowledge.

Why it matters

Unused functionality is not free — it must be maintained, documented, and understood by every developer who reads the code. Speculative generality makes current code harder and provides value that may never arrive.

When to use

  • Any time you hear yourself say 'we might need this later'
  • When adding configuration options that no current feature requires
  • When building extension points before there are extensions to extend
  • When writing code to handle edge cases that don't yet exist in production

When NOT to use

  • Security, compliance, and privacy — design these in from the start, never retrofit
  • Infrastructure decisions that are very expensive to change later (database choice, wire protocol)
  • Accessibility — it's much harder to add later than to design in from day one

Trade-offs

+

Less code to write, maintain, and understand today

Sometimes the cost of retrofitting really is higher than building it upfront

+

Abstractions built when both use cases exist are almost always better

Requires trust that refactoring is cheap — only true with good tests and team discipline

+

Avoids dead code that clutters the codebase indefinitely

Can be used to justify technical debt — 'we'll add error handling when we need it'

In production

Basecamp / DHH

37signals actively practices YAGNI — features are built for current customers, not hypothetical ones

GitHub (early)

GitHub launched with no enterprise features — added them as actual enterprise customers arrived with actual requirements

SQLite

No network server, no user authentication — YAGNI-driven design; use cases that need those features use a different database

Industry adoption

4/5Widely adopted — mainstream at medium-to-large engineering orgs.

Related principles