DEV Community

Cover image for Don’t Over-Engineer: Why the Best Code is Code You Didn’t Write (YAGNI)
Mohamed Ahmed
Mohamed Ahmed

Posted on

Don’t Over-Engineer: Why the Best Code is Code You Didn’t Write (YAGNI)

Every developer has fallen into this trap:

  1. We don’t need this feature today, but what if the client wants it next month?
  2. Let’s build a flexible plugin system just in case we switch databases later.
  3. Let's write an abstract factory pattern here so it’s extensible .

Then six months pass:

  • The code was never used.
  • It is full of bugs.
  • Nobody wants to delete it because nobody remembers why it’s there.

Welcome to the trap of Over-Engineering.

The fix? YAGNI: You Aren't Gonna Need It.

Why Extra Code Hurts Your Project
Writing code for problems you don't have yet creates real trouble today:

  • More bugs: Code you don't write cannot break.
  • Slower changes: Unused code gets in the way every time you try to update simple features.
  • Confused teammates: Other developers waste hours trying to figure out why a complex system exists when it only does one simple thing.

Building for the future isn't "being prepared." It's creating extra work for features that might never exist.

Step 1: Solve Today’s Problem, Not Tomorrow’s Guesswork
Imagine your app needs to send a welcome email when a user signs up.

❌ The Over-Engineered Approach

// Building an extensible notification engine for 5 channels on day 1
interface NotificationStrategy { send(msg: Message): Promise<void>; }
class EmailStrategy implements NotificationStrategy { ... }
class SMSStrategy implements NotificationStrategy { ... }
class PushStrategy implements NotificationStrategy { ... }
class DiscordWebhookStrategy implements NotificationStrategy { ... }

class NotificationDispatcher {
  private strategies: Map<string, NotificationStrategy>;
  dispatch(type: string, msg: Message) { ... }
}
Enter fullscreen mode Exit fullscreen mode

You built a massive notification system before sending a single email.

✅ The YAGNI Approach

// Simple, direct, easy to test
import { sendEmail } from './emailService';

export async function sendWelcomeNotification(userEmail) {
  return sendEmail({
    to: userEmail,
    subject: "Welcome aboard!",
    body: "Thanks for joining us."
  });
}
Enter fullscreen mode Exit fullscreen mode

When your team actually decides to add SMS alerts next year, that is the right time to make it flexible. Not before.

Step 2: The 3 Questions to Ask Before Adding Extra Code
Before you add a new helper function, extra setting, or complex class, ask yourself:

  1. Do we need this for our app right now?

    (If No → Don't write it.)

  2. Will it be twice as hard to add this later when we actually need it?

    (If No → Wait until you need it.)

  3. Does this make the current code harder to read?

    (If Yes → Keep it simple.)

Step 3: Common Traps to Avoid

  1. The Settings Trap

    Creating huge .json or .env files for values that never change. Just put the value directly in the code until you actually need to change it.

  2. The "Just In Case" Parameters

// Bad: Adding extra options you don't use
function calculateTotal(price, taxRate, discount = 0, currency = "USD", applyShippingFee = false) { 
  // ... 
}
Enter fullscreen mode Exit fullscreen mode

If your app only calculates local prices in one currency, don't add 4 unused parameters. Keep it to calculateTotal(price, taxRate). You can always add parameters later when your app expands.

  1. Optimizing Too Early

Spending days building a fancy cache system before checking if your app is actually slow.

When to Plan for the Future
YAGNI does not mean writing bad or messy code.

Good code design means making your code easy to change, not building every possible feature on day one.

  1. Bad Plan: Building an abstract plugin system today.
  2. Good Plan: Writing simple, clean functions so you can easily change them tomorrow.

Final Thought
Keeping things simple is hard. It takes practice to look at a feature and say, "We don't need this yet."

Write the simplest code that solves today's problem. Make it clean, clear, and easy to change when the future actually comes.

Future you will be happy there is less code to read.

Top comments (0)