From grimoire
Guides decisions to add features or abstractions only when required by current concrete requirements, avoiding unnecessary complexity.
How this skill is triggered — by the user, by Claude, or both
Slash command
/grimoire:apply-yagni-principleThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Don't build it until you need it. Every line of code has a lifetime maintenance cost; code you don't write has none.
Don't build it until you need it. Every line of code has a lifetime maintenance cost; code you don't write has none.
Adopted by: Google (Engineering Practices: "avoid premature generalization"), Basecamp (Shape Up methodology explicitly bans imagined requirements), Spotify (engineering blog advocates YAGNI as default), Extreme Programming (Kent Beck) — unanimous adoption across agile and lean engineering cultures. Impact: Fowler cites that unused features account for 64% of software features in a typical enterprise application (Standish CHAOS Report baseline). Each speculative feature costs an estimated 3x its initial build cost in total lifecycle expense (planning + build + test + maintain + eventually delete). Google's "Software Engineering at Google" (2020) documents that premature abstraction is among the top causes of unnecessary complexity in large codebases. Why best: The alternative — building for anticipated future needs — requires predicting requirements correctly. Requirements change: Standish Group finds 45% of features in shipped software are never used, and 19% are used rarely. Building for a future that arrives differently than predicted produces dead code that must be maintained, abstracted, and eventually deleted. KISS addresses how to implement things simply; YAGNI addresses whether to implement them at all.
Sources: Beck & Fowler, "Planning Extreme Programming" (Addison-Wesley, 2000); Fowler, "Refactoring" 2nd ed. (2018); Winters, Manshreck & Wright, "Software Engineering at Google" (O'Reilly, 2020); Standish Group CHAOS Report (2015)
Before writing a line of code, state the specific, current requirement in one sentence. If you can't, stop.
If the requirement is "might", "someday", or "when we need it", that's YAGNI territory — don't build it.
Every proposed abstraction, config option, or extension point is a YAGNI candidate unless there are two or more concrete current uses.
Ask before adding:
| Proposal | YAGNI challenge |
|---|---|
| Plugin system | "Name two current plugins that require this." |
| Config flag | "Who specifically needs this toggle today?" |
| Abstract base class | "What are the two concrete subclasses right now?" |
| Generic data pipeline | "Which three current pipelines justify a framework?" |
| Versioned API | "Is there a current client that requires v1 and v2 simultaneously?" |
If the answer is "not yet" or "probably someone later", don't build it.
Don't generalize on the first or second occurrence of a pattern. Wait for the third.
# First occurrence — implement directly
def send_order_confirmation(order):
send_email(order.user.email, "Order confirmed", render_order_template(order))
# Second occurrence — still implement directly, note the similarity
def send_shipping_notification(shipment):
send_email(shipment.user.email, "Shipped", render_shipment_template(shipment))
# Third occurrence — NOW extract the abstraction
def send_notification(recipient_email, subject, body):
send_email(recipient_email, subject, body)
Premature abstraction on the first occurrence encodes today's assumptions into the interface. By the third occurrence, the real shape of the abstraction is visible.
Flag these patterns in PR review as YAGNI violations:
# YAGNI violation — "just in case" parameter
def create_user(name, email, role="user", legacy_id=None, migration_source=None):
# legacy_id and migration_source never used in any current caller
...
# YAGNI violation — unused extension point
class PaymentProcessor:
def process(self, payment):
return self._process_impl(payment)
def _process_impl(self, payment): # indirection with no current purpose
...
# YAGNI violation — dead configuration branch
ENABLE_NEW_CHECKOUT = os.getenv("ENABLE_NEW_CHECKOUT", "false")
if ENABLE_NEW_CHECKOUT == "true":
# this path was never enabled in production
...
Request removal, not "we'll use it later."
YAGNI is not an excuse to ignore real current problems:
| Situation | Correct response |
|---|---|
| Known bug that will definitely be hit | Fix it — that's a current requirement |
| Scaling problem that is 2 weeks away at current growth | Fix it — it's current |
| Abstraction needed for a feature in the current sprint | Build it — it's current |
| "We might need multi-tenancy in 18 months" | YAGNI — don't build it |
| "This will be easier to test if we add an interface" | Build it — testability is a current requirement |
"But what if we need to support multiple currencies later?" is the most common form of YAGNI pressure. Respond with:
Most "what if" abstractions are retrofittable in a day when actually needed, but cost weeks of complexity over their lifetime if added speculatively.
Using YAGNI to justify shortcuts. "We don't need error handling yet" is not YAGNI — error handling is a current requirement of correct software. YAGNI prevents speculative features, not required correctness.
Deferring until it's too late. YAGNI works when you have confident refactorability. If the architecture makes change expensive, YAGNI breaks down. Keep code clean so you can add things when actually needed.
Confusing YAGNI with KISS. KISS: implement the current requirement simply. YAGNI: don't implement requirements that don't exist yet. Both apply independently to every feature decision.
npx claudepluginhub jeffreytse/grimoire --plugin grimoireEnables and configures Pragmatic Guard Mode to enforce YAGNI and prevent over-engineering. Manages .architecture/config.yml for intensity levels, triggers, and exemptions. Use for simplicity-focused development.
Prevents feature creep with checklists for validating user needs, measuring impact, assessing complexity, defining MVPs, and managing scope in software projects.
Applies KISS, YAGNI, and Principle of Least Astonishment to simplify code when designing solutions, adding features, or refactoring.