Few books have influenced everyday software development as much as Clean Code. It taught a generation of engineers to value readability, naming, small functions, and clarity. I learned from it too, and, like many others, I try to apply its principles if I can.

But the broader message behind it is often taken too far. Readability is one important goal in software engineering, but it is not the only one. It has to be balanced against other constraints. Once that balance is turned into a rule, as the book often encourages, the outcomes can start to suffer. Code is not automatically better just because it reads nicely. Sometimes the more complex, repetitive, or unabstracted solution is the better one. Not because readability does not matter, but because it is only one constraint among many.

To be clear: I care deeply about readable code. I try to write good, readable, and easily comprehensible code every day. But treating readability as the highest goal, rather than as one factor among many, leads to poor decisions.

Everything Is a Tradeoff

Readability trades off against other constraints. One of the most important is time. Consider a function with 20 lines. You could split it into four sub-functions of 5 lines each to make it more readable. But doing so takes time. In most cases, that is a good investment: we read code more than we write it, so the upfront cost pays off later. But what if the code is just a verification script or a one-off codemod that will be deleted after running once? Then spending extra time on readability is a poor tradeoff.

Readability also trades off against performance. In React, useCallback and useMemo add noise and reduce readability. If readability were the highest goal, you would never use them. But they are sometimes necessary to make React perform well. Removing them for the sake of cleaner code would hurt the user experience.

Or take DRY (Don’t Repeat Yourself), one of Clean Code’s core principles. Follow it too strictly, and you abstract too early. You pull code into a shared function to avoid duplication, even though the two use cases will later diverge. Now your abstraction becomes technical debt. The right choice is not to eliminate all duplication, but to wait until the abstraction is clear and stable.

The same is true of almost any coding principle. Immutable data can use more memory. Reusable code can be harder to change. Small functions can obscure the overall flow. No coding principle is universal. Whether it helps or hurts depends on the situation.

And ultimately, your most important job is not writing readable code, it is creating business success. Your manager cares about delivering value that can be sold. Your customers care about the problems you solve, not whether your code is properly abstracted and well named. Doing those things well takes significant time, time that might be better invested elsewhere to create business impact.

This does not mean you should write sloppy code. Short-term business pressure versus long-term maintainability is itself a tradeoff. Rushing features out the door with poor code quality will slow you down later. But obsessing over perfect abstractions and pristine naming while missing deadlines and losing market opportunities is equally harmful.

Read It Anyway

So why is Clean Code dangerous? Because it presents engineering tradeoffs as moral absolutes. The book does not just teach techniques, it judges you for not using them. If you do not follow its principles, you are doing bad, sloppy work. That framing turns situational decisions into a test of your professionalism, and it pushes engineers toward dogmatic thinking rather than contextual judgment.

The techniques themselves are valuable. Small functions, clear naming, removing duplication, these are useful tools. But there is no such thing as universally “clean” code, only code that makes the right tradeoffs for its context.

I still think Clean Code is worth reading. Learn the techniques. Understand the reasoning. But treat the book as a collection of useful patterns, not a moral framework. Apply the ideas where they make sense. Ignore them where they do not.

What makes someone a good engineer is not how strictly they follow one philosophy, but how well they understand the tradeoffs they are making.


I’d genuinely be interested to hear your thoughts. Please drop your feedback on daily.dev or LinkedIn! <- This is not marketing talk, I actually care!