It’s my day off…

I open LinkedIn, and there it is. Another post preaching about WET > DRY, with someone proudly declaring,

WET is better bro, you shouldn’t repeat code until you’ve wrote it 3 times.

Let’s back up a minute.

Ok so, here’s the thing: WET > DRY doesn’t make sense, at all.

This is a misunderstanding of what DRY even means.

DRY—Don't Repeat Yourself—isn't some rigid rule that forces you to abstract everything the moment you spot a duplicate line. It's a principle aimed at eliminating the duplication of knowledge, not code.

It’s about reducing maintenance headaches, avoiding subtle inconsistencies, and keeping your codebase sane.

Saying “wait until you’ve written it three times” is about when to abstract, not about whether DRY is valid. Conflating the two is like blaming electricity for a toaster fire.

DRY is a principle. Timing your abstractions is a strategy.

Different tools.
Different purposes.

We’re here to talk about what DRY is, so let’s do that…

What is knowledge duplication?

Imagine you see something like this scattered throughout a codebase:

if ($user->role === 'admin') {
    // give access to the dashboard
}

if ($user->role === 'admin' || $user->is_superuser) {
    // show the edit button
}

if ($user->role === 'admin' && !$user->is_suspended) {
    // allow deleting a record
}

Every one of these is someone’s idea of what “admin” means. And each one is just a little different. That’s not just code repetition—it’s knowledge duplication. What happens when the definition of “admin” changes? Say, we now require that admins also have a verified flag set to true.

You now have to hunt down every instance and hope you don’t miss one, and it gets confusing, do you apply this to each duplication of knowledge?

That’s the heart of it.

You don’t blindly apply DRY to every instance of code repetition, but you absolutely should apply it when what’s being repeated is knowledge—especially business logic that could change.

What is code duplication?

Let’s say you’re writing a basic form handler, and you need to trim user input for a couple of fields:

$name = trim($request->input('name'));
$email = trim($request->input('email'));

Looks, kinda like duplicated code, right? So you think, oh hey, tHiS iS ViOlAtInG dRy, lets do something about it, so you:

// Abstracted method somewhere else.
function clean($field) {
    return trim($request->input($field));
}

$name = clean('name');
$email = clean('email');

You saved some code duplication. But at what cost?

You’ve added a layer of indirection for no real gain. There’s no duplicated knowledge here. Everyone already knows what trim() and $request->input() do. This kind of repetition is harmless—and even beneficial, because it’s clear and explicit.

Now imagine someone else looking at this six months later and seeing this:

$name = clean('name');

Wait—does clean() just trim? Does it also escape HTML? Validate email addresses? Remove profanity? You don’t know until you go hunting for it.

This is why the “write it three times” advice can be useful: it’s not about avoiding DRY—it’s about avoiding premature abstraction. You want patterns to emerge organically, not because you couldn’t bear to copy-paste two lines.

Want another example? No? Tough…

Imagine you're working on a page with a few different buttons:

<button class="btn btn-primary">Save</button>
<button class="btn btn-danger">Delete</button>
<button class="btn btn-secondary">Cancel</button>

A well-meaning developer comes along and decides this is repetition, and creates a helper (this code is disgusting by the way):

function button($label, $type = 'primary') {
    return "<button class=\"btn btn-{$type}\">{$label}</button>";
}

echo button('Save');
echo button('Delete', 'danger');
echo button('Cancel', 'secondary');

You’ve just traded clarity for abstraction. If someone unfamiliar with the helper sees this:

echo button('Cancel', 'secondary');

They now have to go look up what the function does, what classes it applies, whether it's safe to use in modals, etc.

Meanwhile, the original version is self-evident HTML that any frontend dev can skim and understand instantly.

Sometimes…

…. repetition is just repetition and it’s the right choice.

I’ve seen plenty of people toss around WET (Write Everything Twice) is better as if it's the antidote to DRY, but that’s a misunderstanding of both concepts.

WET is an abstraction strategy. Knowing when to apply an abstraction and avoiding premature cases of it.

DRY isn’t repeated code.
DRY isn’t repeated code.
DRY isn’t repeated code.

It’s about repeated knowledge.

If you’re repeating logic that encapsulates a rule—like the definition of something or some specific business logic. That’s the kind of repetition you need to eliminate.

It’s not about reducing every line of code.

There's a widespread misunderstanding and actually quite worrying.

Right, I’m off to chill.

Byeeeeeeeeeeee.