~/portfolio
← Back to writing
8 October 2025Updated 25 April 2026

Clean Code is Great.... Until It Isn't

Clean code is a tool, not a religion. When messy code that ships beats elegant code that doesn't — and why clarity matters more than cleanliness.

By Akin Ibitoye1 view

Key Takeaways

  • Clean code is a tool, not a religion: it earns its keep when code outlives its first deploy and burns time when it doesn't.
  • In time-boxed work (hackathons, prototypes, throwaway scripts), clarity beats cleanliness — readable-but-ugly is better than abstracted-but-opaque.
  • The honest test: would future-you understand this in a week without spelunking three files? If yes, it is clean enough.

We’re always told to write clean code. It’s like the first rule of being a “real” developer. Use good variable names, keep functions short, don’t repeat yourself, comment just enough, and make everything look neat. And yeah — it matters. Clean code makes things easier to read, easier to fix, and easier to hand off without causing chaos.

But here’s the thing: sometimes, clean code isn’t the best code. And sometimes… you have to break stuff to make it good.

When does clean code slow you down?

I’ve worked on a few uni projects and hackathons where we were racing the clock. And in those moments, trying to make everything perfect just slowed us down. We needed something that worked — fast. Refactoring for elegance or splitting logic into perfect little modules was just not the priority.

Sometimes, messy code that works is better than clean code that’s half done.

Why break things on purpose?

There’s this weird moment in some projects where you realize: the only way forward is to break something. Maybe it’s a function that’s too abstract. Maybe it’s a structure that looked clean but doesn’t fit the new logic. You tear it down, rewrite it, and suddenly everything makes more sense.

It feels wrong at first — like you’re undoing your own hard work. But breaking things is part of building. You can’t always improve without destroying a few “clean” ideas that don’t hold up.

What's the difference between clean and clear?

One thing I've learned is that clean code doesn't always mean clear code. You can have a beautifully abstracted function that hides all the complexity — but then no one knows what it actually does unless they dig through three files. I've written code like that. It looked nice, but even I got confused later.

Here's the kind of thing I mean. The "clean" version, full of helpers:

const total = items
  .filter(isEligible)
  .map(applyDiscount)
  .reduce(sumPrice, 0);

Reads great — until you realise isEligible, applyDiscount, and sumPrice are three jumps away in two files, and the actual rule (UK customers get 10% off orders over £50) is split across all of them. The "ugly" inline version is sometimes the clearer one:

let total = 0;
for (const item of items) {
  if (item.country !== "UK") continue;
  const discount = item.subtotal > 50 ? 0.10 : 0;
  total += item.subtotal * (1 - discount);
}

Twelve lines, zero indirection. Future-you can read it in 5 seconds. The "clean" version requires a treasure hunt.

Now I try to focus more on clarity. If the logic is weird or experimental, I'd rather write it out in a way that's obvious, even if it's a bit ugly.

Why doesn't real-world code look like the textbook?

In uni, we’re taught best practices. And yeah, they matter. But in real-world projects — especially quick ones — you sometimes have to break the rules. Maybe you hardcode something. Maybe you duplicate a bit of logic. Maybe you skip writing tests for a throwaway script.

And that’s okay. Not everything needs to be production-grade.

So what's the actual rule?

Clean code is a tool, not a religion. Use it when it helps. Ignore it when it doesn’t. The goal is to build stuff that works, that people can understand, and that you can maintain if it sticks around.

If it’s a one-off thing or a prototype, don’t stress too much. Just make sure it’s clear enough that future-you won’t hate past-you.

Anyway, that’s just my take. Still figuring it out, but this mindset has saved me a lot of time (and headaches). Would love to hear how other devs balance clean code vs. fast code — especially in messy projects.

Frequently asked questions

Is clean code always the right goal?
No. Clean code is a tool that pays off when code outlives its first deploy and gets read by other people. In short-lived contexts — hackathons, prototypes, throwaway scripts — over-engineering for cleanliness costs more time than it saves. The honest test is whether future-you will thank you, not whether the code looks elegant on a screen.
What is the difference between clean code and clear code?
Clean code follows formal conventions: short functions, no duplication, well-named variables, tight abstractions. Clear code is something narrower: code where the intent is obvious without spelunking three files. They overlap, but a beautifully abstracted function can hide all the complexity and stop being clear, even while it stays clean.
When is it okay to break clean-code rules?
When the code is short-lived, when the rule hides intent, or when shipping is the constraint. A duplicated 5-line block in a one-off script is fine. A clever abstraction that confuses every future reader is not. The rule is the goal, not the action — break the rule when keeping it works against the goal.
Why does shipping messy code sometimes beat clean unfinished code?
Because users only ever benefit from code that runs. A working messy implementation is a baseline you can refactor; an elegant half-finished one is a future you, not a present one. In time-boxed work this matters more than usual: shipping a working v1 buys you the right to write the cleaner v2.