🎯

keep-it-simple

🎯Skill

from elliotjlt/claude-skill-potions

VibeIndex|
What it does

Prevents premature complexity by resisting over-engineering and enforcing the Rule of Three before adding abstractions.

πŸ“¦

Part of

elliotjlt/claude-skill-potions(26 items)

keep-it-simple

Installation

git cloneClone repository
git clone https://github.com/ElliotJLT/Claude-Skill-Potions.git ~/.claude/skills
git cloneClone repository
git clone https://github.com/ElliotJLT/Claude-Skill-Potions.git .claude-skills
ConfigurationMCP configuration (may be incomplete)
{ "hooks": { "UserPromptSubmit": [ { "hooks": [ { ...
πŸ“– Extracted from docs: elliotjlt/claude-skill-potions
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

|

Overview

# Keep It Simple

Claude loves elegant abstractions. User asks for a button, Claude builds a

component factory with theming support. The problem: abstractions have costs.

They obscure intent, add indirection, and often solve problems that never

materialize. This skill enforces YAGNI - You Aren't Gonna Need It.

When To Activate

  • About to create a factory, builder, or abstract base class
  • Proposing a config-driven solution
  • Using phrases like "for flexibility" or "in case we need"
  • Creating a utility for something done twice
  • Adding parameters "for future use"
  • Building infrastructure before the feature

Instructions

The YAGNI Test

Before adding abstraction, answer honestly:

```markdown

Complexity Check

I want to add: [describe the abstraction]

Because: [your justification]

Is this solving a problem we have TODAY?

  • [ ] Yes, we have 3+ concrete cases now
  • [ ] No, but we might need it later

If "might need later": Don't build it. Stop.

```

The Rule of Three

Abstract when you have three concrete cases, not before:

| Situation | Action |

|-----------|--------|

| 1 case | Just write it |

| 2 cases | Copy-paste is fine. Note the duplication. |

| 3 cases | Now consider abstracting |

```

// With 1 button: just make the button

// With 2 buttons: copy-paste is fine

// With 3+ buttons: NOW consider a component

```

Abstraction Warning Signs

Watch for these phrases in your thinking:

  • "For flexibility..." β†’ Flexibility for what? Do we need it?
  • "In case we need to..." β†’ We don't need to yet.
  • "This could be configurable..." β†’ Is anyone asking to configure it?
  • "To support future..." β†’ Future isn't asking for support.
  • "For extensibility..." β†’ Extend it when you need to.

Watch for these patterns:

  • Factory that produces one type
  • Config object with one option
  • Abstract class with one implementation
  • Utility function used once
  • Parameters that are always the same value

Simplest Solutions

| Instead of | Try |

|------------|-----|

| Factory pattern | Direct instantiation |

| Abstract base class | Concrete class |

| Config-driven behavior | Hardcoded behavior |

| Dependency injection | Direct imports |

| Custom event system | Callbacks |

| Generic utility | Inline code |

When Abstraction IS Right

Abstraction is warranted when:

  • You have 3+ concrete, existing cases
  • The pattern is stable (not still changing)
  • The duplication is causing actual bugs
  • You're building a library for others

Output Format

When resisting complexity:

```markdown

Keeping It Simple

Considered: [the abstraction]

Rejected because: [only N cases / speculative / etc.]

Instead: [simpler approach]

```

When complexity is warranted:

```markdown

Abstraction Justified

Adding: [the abstraction]

Because: [3+ cases / causing bugs / stable pattern]

Cases: [list the concrete cases]

```

NEVER

  • Build factories for single types
  • Create abstract classes before concrete ones
  • Add config options nobody asked for
  • Build "infrastructure" before the feature
  • Say "for future extensibility" as justification
  • Create utilities for one-time operations

ALWAYS

  • Start with the simplest thing that works
  • Wait for three concrete cases before abstracting
  • Prefer duplication over premature abstraction
  • Let patterns emerge from real usage
  • Ask "do we need this TODAY?"

Example

User: "Add a way to send notification emails"

Over-engineered approach:

```

NotificationFactory

β”œβ”€β”€ EmailNotification

β”œβ”€β”€ SMSNotification (might need later!)

β”œβ”€β”€ PushNotification (could be useful!)

└── NotificationConfig

β”œβ”€β”€ templates

β”œβ”€β”€ retryPolicy

└── queueSettings

```

YAGNI approach:

```python

def send_notification_email(user, subject, body):

email_service.send(

to=user.email,

subject=subject,

body=body

)

```

Why simpler is better:

  • User asked for email. Just do email.
  • SMS and Push aren't requested. Don't build them.
  • Config can be added when there's something to configure.
  • If we need SMS later, we'll add it then.

The 5-line function solves the actual problem. The factory solves imaginary ones.

What DOESN'T work:

  • "Just in case": Building for cases that don't exist yet. They may never exist.
  • "It's more elegant": Elegance is not a requirement. Working is a requirement.
  • "This pattern is best practice": Best practices are context-dependent. A pattern for 100 cases is overkill for 1.
  • Abstracting after 2 cases: You don't know the pattern yet. Wait for the third.
  • Config files for one setting: Hardcode it. Add config when there are multiple settings to configure.
  • "Future-proofing": You can't predict the future. Build for now.
  • Dependency injection everywhere: Direct imports are fine. DI is for when you actually need to swap implementations.
  • Generic utilities from day one: Write the specific code. Extract utility when you have 3+ uses.
  • "Flexibility": Flexibility without a use case is just indirection.
  • Building the platform before the product: Ship the feature. Build infrastructure when you need it.

More from this repository10

🎯
pre-mortem🎯Skill

Conducts a proactive risk analysis by imagining potential project failure scenarios and developing preventative strategies.

🎯
battle-plan🎯Skill

Orchestrates a comprehensive planning ritual by sequentially using rubber-duck, pre-mortem, and ETA skills to thoroughly assess and validate development tasks before coding begins.

🎯
you-sure🎯Skill

Pauses and presents a detailed checklist before executing potentially destructive or high-impact operations, requiring explicit confirmation.

🎯
rubber-duck🎯Skill

Helps users articulate technical problems clearly by asking structured diagnostic questions before proposing solutions.

🎯
eta🎯Skill

Generates data-driven time estimates for coding tasks by analyzing codebase scope, complexity, and potential risks.

🎯
dont-be-greedy🎯Skill

Prevents Claude from exploiting loopholes or manipulating instructions by enforcing ethical boundaries and responsible interaction.

🎯
pipeline🎯Skill

Sequentially executes multi-stage tasks with strict stage-by-stage progression and checkpoint validation.

🎯
fan-out🎯Skill

Distributes and processes a list of inputs across multiple parallel function calls to improve efficiency and throughput.

🎯
split-decision🎯Skill

I understand. Here's a concise one-sentence description for the "split-decision" skill: Systematically presents multiple viable options with detailed trade-offs before recommending any architectur...

🎯
debug-to-fix🎯Skill

Systematically debug issues by clarifying the problem, investigating root causes, implementing fixes, and verifying solutions through a structured, methodical approach.