> ## Documentation Index
> Fetch the complete documentation index at: https://docs.karpathy.phronesisagent.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Simplicity First: write minimum viable code for LLMs

> Simplicity First enforces minimum viable code. No speculative abstractions, no unrequested features, and no error handling for impossible scenarios.

LLMs have a strong pull toward over-abstraction. Ask for a discount function and you might get a strategy pattern with abstract base classes, dataclasses, and a calculator object — all for a single multiplication. Simplicity First is the discipline of writing the minimum code that actually solves the stated problem, deferring every other complexity until the moment it's genuinely needed.

## The rules

* **No features beyond what was asked.** If the request didn't mention it, don't build it.
* **No abstractions for single-use code.** One call site does not need an interface.
* **No "flexibility" or "configurability" that wasn't requested.** Optional parameters, pluggable backends, and configuration systems are features — treat them that way.
* **No error handling for impossible scenarios.** Handle the errors that can actually happen.
* **If you write 200 lines and it could be 50, rewrite it.** The first draft is not the final answer.

## The test

Ask yourself: "Would a senior engineer say this is overcomplicated?"

If yes, simplify. Every time.

## Over-abstraction example

**Request:** "Add a function to calculate discount"

<Warning>
  **What LLMs do wrong — strategy pattern for a single multiplication**

  ```python theme={null}
  from abc import ABC, abstractmethod
  from enum import Enum
  from typing import Protocol, Union
  from dataclasses import dataclass

  class DiscountStrategy(ABC):
      @abstractmethod
      def calculate(self, amount: float) -> float:
          pass

  class PercentageDiscount(DiscountStrategy):
      def __init__(self, percentage: float):
          self.percentage = percentage

      def calculate(self, amount: float) -> float:
          return amount * (self.percentage / 100)

  class FixedDiscount(DiscountStrategy):
      def __init__(self, fixed_amount: float):
          self.fixed_amount = fixed_amount

      def calculate(self, amount: float) -> float:
          return min(self.fixed_amount, amount)

  @dataclass
  class DiscountConfig:
      strategy: DiscountStrategy
      min_purchase: float = 0.0
      max_discount: float = float('inf')

  class DiscountCalculator:
      def __init__(self, config: DiscountConfig):
          self.config = config

      def apply_discount(self, amount: float) -> float:
          if amount < self.config.min_purchase:
              return 0
          discount = self.config.strategy.calculate(amount)
          return min(discount, self.config.max_discount)

  # Usage requires 30+ lines of setup for a simple calculation
  ```
</Warning>

<Check>
  **The correct approach — one function until complexity is actually needed**

  ```python theme={null}
  def calculate_discount(amount: float, percent: float) -> float:
      """Calculate discount amount. percent should be 0-100."""
      return amount * (percent / 100)

  # Usage
  discount = calculate_discount(100.0, 10.0)  # $10 off
  ```
</Check>

## Speculative features example

**Request:** "Save user preferences to database"

<Warning>
  **What LLMs do wrong — building cache, validation, and notifications nobody asked for**

  ```python theme={null}
  class PreferenceManager:
      def __init__(self, db, cache=None, validator=None):
          self.db = db
          self.cache = cache or InMemoryCache()
          self.validator = validator or DefaultValidator()

      def save(self, user_id: int, prefs: dict,
               merge: bool = True,
               validate: bool = True,
               notify: bool = False) -> bool:
          """Save preferences with optional merging, validation, and notifications."""

          if validate:
              errors = self.validator.validate(prefs)
              if errors:
                  raise ValidationError(errors)

          existing = self.get(user_id) if merge else {}

          if merge:
              existing.update(prefs)
              prefs = existing

          self.db.execute(
              "UPDATE users SET preferences = ? WHERE id = ?",
              (json.dumps(prefs), user_id)
          )

          if self.cache:
              self.cache.set(f"prefs:{user_id}", prefs)

          if notify:
              self.notify_preference_change(user_id, prefs)

          return True

      def notify_preference_change(self, user_id: int, prefs: dict):
          # Another 30 lines for a feature nobody asked for
          pass
  ```
</Warning>

<Check>
  **The correct approach — just what was asked**

  ```python theme={null}
  def save_preferences(db, user_id: int, preferences: dict):
      """Save user preferences to database."""
      db.execute(
          "UPDATE users SET preferences = ? WHERE id = ?",
          (json.dumps(preferences), user_id)
      )
  ```
</Check>

## When to add complexity

Complexity earns its place only when you actually need it — not when you might need it someday.

<Tip>
  Add caching when performance data shows it's needed. Add validation when bad data actually appears. Add merging when the requirement is stated. Refactor to a class when you have multiple call sites with shared state. Until then, the simple version is the correct version.
</Tip>

The simple versions are faster to implement, easier to test, easier to understand, and easier to refactor when real complexity arrives. Good code solves today's problem simply — not tomorrow's problem prematurely.
