Dry Principle vs Kiss Principle
DRY says never repeat yourself; KISS says keep it stupidly simple. Both are good advice that turn toxic when worshipped. Here's which one you should default to when they fight.
The short answer
Kiss Principle over Dry Principle for most cases. DRY abstractions are the most expensive mistakes in a codebase to unwind, because they couple things that only looked similar.
- Pick Dry Principle if have proven, semantically identical logic repeated three-plus times and a single owner of the meaning — extract it, DRY pays off
- Pick Kiss Principle if unsure whether two things will diverge, you're early in a design, or the abstraction would need parameters and flags to fit both callers — stay simple, duplicate
- Also consider: They are not opposites. Apply KISS by default, reach for DRY only after duplication has earned the abstraction with real, repeated evidence.
— Nice Pick, opinionated tool recommendations
What they actually mean
DRY — Don't Repeat Yourself — was coined in The Pragmatic Programmer and is misquoted constantly. The original is about a single authoritative source of knowledge, not about deleting any two lines that look alike. KISS — Keep It Simple, Stupid — comes from aircraft engineering and says the best system is the one a tired person can fix at 3am. The trap is treating both as commandments. DRY weaponized becomes a maze of base classes, mixins, and config flags that exist only to avoid typing the same thing twice. KISS weaponized becomes copy-paste sprawl where one bug fix has to be applied in nine places and you miss the tenth. Neither is a religion. DRY is about knowledge; KISS is about complexity. Most fights between them are actually a fight about whether two pieces of code share the same meaning or just the same shape — and shape is a liar.
Where DRY earns its keep
DRY is non-negotiable for one thing: a single source of truth. Tax rates, validation rules, the wire format of an API, an enum of states — these have one correct value and duplicating them is how production catches fire. If your discount logic lives in the frontend and the backend and a cron job, you will eventually ship three different answers and a customer will screenshot it. That's the legitimate DRY win, and it's huge. Where DRY rots is when people apply it to incidental duplication — two functions that happen to have similar control flow today but model genuinely different concepts. You extract a shared helper, then six months later one caller needs an exception, so you add a boolean. Then another flag. The abstraction now has more configuration than the duplication ever cost. DRY the knowledge, never the coincidence. The Rule of Three exists precisely because two occurrences aren't enough evidence.
Where KISS earns its keep
KISS wins because simple code fails in ways you can see, fix, and reason about alone. A dumb 40-line function with some repetition is readable by anyone on the team on day one. A clever metaprogrammed factory that generates that same behavior is a four-hour onboarding cost and a debugger that steps into nowhere. Simplicity also keeps optionality: duplicated code is trivially deletable and trivially divergent, which is exactly what you want before you understand the domain. The cost of KISS is real — you do maintain duplication, and a careless change can leave copies out of sync. But that failure is local and obvious, usually caught in review or a test. The failure mode of premature abstraction is global and invisible: a single change ripples through callers you forgot existed. Sandi Metz said it best — duplication is far cheaper than the wrong abstraction. Believe her.
The verdict
KISS is the default; DRY is the optimization you apply once you have evidence. Write the simple, slightly-repetitive version first. When duplication appears a third time AND the duplicated thing represents the same knowledge — not just the same shape — extract it under a single owner. That ordering matters because the mistakes are asymmetric. A KISS mistake is a duplicated block you consolidate later in an afternoon. A DRY mistake is a load-bearing abstraction five teams depend on, and unwinding it means re-inlining behavior across modules nobody wants to touch. You can always DRY up simple code; you can rarely simplify a bad abstraction without a rewrite. So when they fight, let KISS win the tie. Reach for DRY deliberately, with proof, never reflexively. Simple and duplicated beats clever and coupled. Stop abstracting on the second occurrence.
Quick Comparison
| Factor | Dry Principle | Kiss Principle |
|---|---|---|
| Core concern | Single source of truth for knowledge | Minimize complexity a human must hold |
| Failure mode | Wrong abstraction couples unrelated code globally | Out-of-sync copies, but local and visible |
| Reversibility | Hard — unwinding an abstraction often needs a rewrite | Easy — duplication consolidates in an afternoon |
| When it's non-negotiable | Values/rules with one correct answer (tax, API format) | Early design, uncertain divergence, onboarding |
| Common misuse | Abstracting incidental same-shape code on occurrence two | Copy-paste sprawl that misses the tenth fix |
The Verdict
Use Dry Principle if: You have proven, semantically identical logic repeated three-plus times and a single owner of the meaning — extract it, DRY pays off.
Use Kiss Principle if: You are unsure whether two things will diverge, you're early in a design, or the abstraction would need parameters and flags to fit both callers — stay simple, duplicate.
Consider: They are not opposites. Apply KISS by default, reach for DRY only after duplication has earned the abstraction with real, repeated evidence.
Dry Principle vs Kiss Principle: FAQ
Is Dry Principle or Kiss Principle better?
Kiss Principle is the Nice Pick. DRY abstractions are the most expensive mistakes in a codebase to unwind, because they couple things that only looked similar. KISS fails cheap and local. When the two collide, simple-but-duplicated beats clever-but-coupled almost every time.
When should you use Dry Principle?
You have proven, semantically identical logic repeated three-plus times and a single owner of the meaning — extract it, DRY pays off.
When should you use Kiss Principle?
You are unsure whether two things will diverge, you're early in a design, or the abstraction would need parameters and flags to fit both callers — stay simple, duplicate.
What's the main difference between Dry Principle and Kiss Principle?
DRY says never repeat yourself; KISS says keep it stupidly simple. Both are good advice that turn toxic when worshipped. Here's which one you should default to when they fight.
How do Dry Principle and Kiss Principle compare on core concern?
Dry Principle: Single source of truth for knowledge. Kiss Principle: Minimize complexity a human must hold.
Are there alternatives to consider beyond Dry Principle and Kiss Principle?
They are not opposites. Apply KISS by default, reach for DRY only after duplication has earned the abstraction with real, repeated evidence.
DRY abstractions are the most expensive mistakes in a codebase to unwind, because they couple things that only looked similar. KISS fails cheap and local. When the two collide, simple-but-duplicated beats clever-but-coupled almost every time.
Related Comparisons
Disagree? nice@nicepick.dev