Clean Code Is Not a Personality

Perfect folder structure, zero linting warnings, DRY everywhere, SOLID strictly followed, shorthand syntax throughout — and the product is broken, the deadline is missed, and nobody can explain what the business logic actually does. Code aesthetics are hygiene. They are not engineering.

Pranta Das
Pranta Das
13 min readUpdated Jun 1, 2026
2views

There is a specific type of code review comment that I have come to recognize on sight.

"This variable name could be more descriptive."

"We should extract this into a separate utility function."

"This violates the single responsibility principle."

"This pattern isn't DRY — we have similar logic in the other module."

"The folder structure here doesn't follow the convention."

These comments are not wrong, exactly. Descriptive names are better than cryptic ones. Utility functions are sometimes the right abstraction. DRY has genuine value. Conventions exist for good reasons.

But I have sat in code reviews where twenty minutes were spent discussing a variable name while a logical error in the same function that would produce incorrect results for a specific input went unmentioned — because the logical error required understanding the domain and the variable name just required having an opinion.

I have watched engineers spend hours perfecting the folder structure of a project that did not yet have a working core feature. Reorganizing imports. Renaming files to be more semantically consistent. Adding an abstraction layer that made the code more architecturally orthodox and harder to follow.

I have seen codebases where DRY had been applied so aggressively that a single shared utility function had seventeen parameters, a comment block explaining which combination of parameters applied to which caller, and a conditional structure so complex that touching it required a meeting.

And I have been in enough teams to notice a pattern: the engineers who are most focused on these aesthetics are not always — are not usually — the engineers who are most effective at building things that work.


What "Clean Code" Has Become

Robert Martin's Clean Code was published in 2008 and it named things that genuinely needed naming. Meaningful variable names. Functions that do one thing. The value of removing redundancy. These are real observations about what makes code easier to work with over time.

But something specific happened to those observations between the book and the culture it produced: they became a religion, and like most religions, the practice gradually detached from the original purpose.

The purpose of meaningful variable names is that future readers — including you, six months later — can understand what the code is doing without having to trace its execution. This is a practical goal: reduce the cognitive load required to work with the code.

The religion version is: spend forty-five minutes in a code review discussing whether user should be authenticatedUser or currentUser or loggedInUser, while the code that handles the case where the user's session has expired incorrectly is sitting untouched in the same file.

The purpose of the single responsibility principle is to prevent individual components from accumulating so much behavior that changes to one concern inadvertently affect another. A useful heuristic for managing complexity in large systems.

The religion version is: split every function that does two things into two functions, create a new class for every distinct behavior, and produce a codebase where a simple feature requires tracing through eleven files because each one has been made beautifully singular in its responsibility.

The purpose of DRY — Don't Repeat Yourself — is to prevent the maintenance problem that arises when the same logic exists in multiple places and needs to be changed in all of them simultaneously. A real problem in large codebases.

The religion version is: extract any two lines that look similar into a shared abstraction, regardless of whether they are actually the same concept or merely coincidentally similar in structure, producing a coupling between things that should be able to evolve independently.

The practice becomes performance. The performance becomes identity. And somewhere along the way the question stopped being "does this code do what it needs to do" and became "does this code reflect well on me."


The Shorthand Trap

Modern programming languages provide concise syntax for common patterns. Arrow functions instead of function declarations. Optional chaining instead of null checks. Destructuring instead of property access. Ternary operators instead of if-else blocks.

These features exist for good reasons. Concise code can be cleaner code — when the reader can parse the concise form as quickly as the verbose form and understand the same thing.

The problem is what happens when conciseness becomes a goal rather than a byproduct. When code is written to be maximally compact because compact code looks sophisticated. When a three-line ternary chain is used where two if-statements would be immediately readable. When a reduce with a complex accumulator function is used where a for loop would be obvious.

// Impressive-looking
const result = data.reduce((acc, { id, value, meta: { type } }) =>
  ({ ...acc, [id]: type === 'active' ? value * 1.2 : value }), {});
 
// Readable
const result = {};
for (const item of data) {
  const multiplier = item.meta.type === 'active' ? 1.2 : 1;
  result[item.id] = item.value * multiplier;
}

Both produce the same output. The first looks like the work of someone who knows the language well. The second is immediately readable by anyone who can read code, including the person who wrote it returning to it eight months later at midnight during a production incident.

The question to ask is: who is this conciseness serving? If the answer is "the reader" — if the compact form genuinely conveys the intent more clearly — then it is the right choice. If the answer is "my sense of how good code looks" — if the compact form requires the reader to decode rather than read — then it is aesthetic engineering, and aesthetic engineering is not serving the product.


DRY Is a Tendency, Not a Commandment

The most destructive misapplication of a principle I have seen repeatedly is DRY applied without judgment.

DRY is genuinely valuable when it prevents the maintenance problem of duplicated logic. If you change how user authentication works and there are twelve places in the codebase that contain a copy of the authentication check, you will miss some of them. That is a real problem and DRY addresses it correctly.

DRY is destructive when it extracts coincidentally similar code into a shared abstraction before it is clear whether the similarity is fundamental or accidental.

Two things can look the same and be fundamentally different. The logic for processing a refund and the logic for processing an initial payment might share structural similarity — both involve an amount, a currency, a user, a transaction record. Extracting them into a shared payment processing function because they are similar is a decision that will make the codebase harder to maintain when they inevitably need to diverge, because payments and refunds have different compliance requirements, different failure modes, and different downstream effects that will accumulate over time.

The principle that is often more useful than DRY is the one that is less often cited: the Rule of Three. Write something once, tolerate it twice, extract it when you see it three times. Because two instances of similar code might still be coincidence. Three instances suggests an actual pattern worth abstracting.

Applied prematurely, DRY couples things that should remain independent. Applied appropriately, it removes genuine redundancy. The difference is not in the principle — it is in the judgment about whether the similarity is fundamental or circumstantial. And that judgment requires understanding the domain, which is harder and less immediately visible than simply noticing that two blocks of code look the same.


The Folder Structure That Nobody Reads

Software projects often have strong conventions about folder structure. Controllers in controllers, services in services, models in models. Or feature-based organization: everything for a feature lives together. Or domain-driven: bounded contexts as the organizing principle.

These conventions are reasonable. A consistent structure reduces the cognitive overhead of finding code in a project you are new to. That is a real benefit.

But I have seen engineers spend significant time reorganizing folder structure in projects where the actual problem was that the code inside the folders did not work correctly. The structure looked professional. The behavior was wrong.

Folder structure is organizational hygiene. It makes navigation easier. It does not make the code correct, performant, secure, or maintainable in any of the ways that actually matter. A perfectly organized codebase where the business logic is incorrect is significantly worse than a messily organized codebase where the business logic is correct — because structure can be changed cheaply and correctness is expensive to retrofit.

The engineer who reorganizes imports and renames folders before the feature works is optimizing the wrong dimension. The engineer who gets the feature working first and then cleans up the organization is making a sensible trade-off. Both codebases will eventually be clean and organized. Only one of them will have shipped.


What Linting Actually Does

Linting tools — ESLint, Prettier, language-specific formatters — are valuable. They enforce consistency automatically, catch a category of common errors, and remove the style debates that would otherwise consume code review time. Using a linter is correct.

But linting catches a narrow category of problems: style inconsistencies, certain classes of syntax errors, some common anti-patterns. It does not catch logical errors. It does not catch wrong implementations of correct requirements. It does not catch security vulnerabilities in business logic, incorrect handling of edge cases, performance problems that emerge from architectural decisions, or any of the dozens of ways that code can be syntactically correct and operationally wrong.

Zero linting warnings is a floor, not a ceiling. The code that passes every lint rule and has no type errors is code that meets a minimum standard. Whether it does what the product requires, whether it handles failure correctly, whether it will perform acceptably under load, whether it can be maintained by the next engineer — none of this is captured by lint output.

An engineer who measures code quality primarily by lint status is measuring whether the floor was reached, not whether the ceiling was approached.


What Actually Demonstrates Engineering Intelligence

The practices described above — clean naming, DRY, SOLID, linting, consistent structure — are not unimportant. They are hygiene. Like personal hygiene, they are expected, they matter for working with others, and their absence is a problem. But their presence is not a signal of exceptional ability. It is the baseline.

What demonstrates engineering intelligence is harder to see and harder to perform.

It is the ability to look at a vague, ambiguous requirement and ask the right clarifying questions before writing code — because the wrong interpretation will mean throwing the work away.

It is the ability to design a data model that will accommodate requirements you do not yet know exist, without over-engineering for requirements that will never arrive.

It is the ability to read a codebase you did not write, understand its behavior from the code rather than the documentation, identify where the behavior diverges from what it should be, and fix it without breaking the parts that work correctly.

It is the ability to make a trade-off decision — between speed and correctness, between simplicity and flexibility, between delivery and quality — and explain clearly why the trade-off is appropriate for the current situation, not as a general principle but as a judgment specific to the constraints that exist right now.

It is the ability to look at a system that is failing in production, form hypotheses about the cause from incomplete information, test those hypotheses efficiently, and restore service while maintaining enough discipline not to introduce new problems in the process of fixing the immediate one.

None of these things appear in a lint report. None of them are captured by folder structure consistency. None of them are demonstrated by aggressive application of DRY or a perfect SOLID architecture.

They are demonstrated by solving hard problems correctly — by building things that work, that can be maintained, that deliver value, and that hold up when reality turns out to be more complex than the initial design anticipated.


The Code Review That Matters

The code review that improves a codebase is not primarily the one that catches variable naming inconsistencies. It is the one that asks: does this code correctly handle the case where the external API returns a 429? What happens if this database transaction is interrupted midway through? Is this the right abstraction for this problem, or is it solving for a future flexibility that we do not currently need and that will make this harder to understand? Are the edge cases in the requirement accounted for, and if not, which ones are acceptable to defer?

These questions are harder to ask than "this variable name could be more descriptive." They require understanding the domain, the system's operational context, and the specific requirement being implemented. They require judgment.

Judgment is not something that is demonstrated by correct application of formatting rules. It is demonstrated by making good decisions under uncertainty about things that actually matter — and code review is one of the most direct opportunities to either ask the questions that matter or spend the time on the ones that don't.


Closing

Code aesthetics matter. Readable code is easier to maintain. Consistent conventions reduce cognitive overhead. DRY prevents real maintenance problems. These things are true and worth caring about.

But they are hygiene, not excellence. They are the expected baseline of professional engineering, not the measure of engineering ability.

The engineers I have worked with who are genuinely exceptional are not the ones with the most pristine folder structures or the most aggressively DRY codebases. They are the ones who understand the systems they are building deeply enough to make good decisions under uncertainty. Who solve the right problems. Who debug things they did not write. Who make trade-offs consciously rather than defaulting to orthodoxy.

Their code is usually readable and reasonably organized. But that is a byproduct of clarity of thought, not the source of it. They write clean code because they think clearly about the problem — not because clean code is their identity.

There is a difference between an engineer who cares about quality and an engineer who cares about appearing to care about quality. The distinction is not always visible in the code. It is visible in the product.


The best engineers I have worked with could write a perfect SOLID architecture and also tell you exactly when not to. The principles were tools in service of the problem, not the goal itself. That's the difference between understanding a principle and performing it.

Share this article
Pranta Das
Pranta Das
Backend Developer & Team Lead · Dhaka, Bangladesh 🇧🇩

Backend Developer & Team Lead building scalable systems and sharing engineering insights from Dhaka, Bangladesh.

Comments

No comments yet — be the first!

Related Articles

The Project Wasn't the Problem: When Poor Ownership Creates Technical Chaos

A project accumulates months of development, dozens of features, and significant complexity. Deadlines are missed. The client is dissatisfied. The project changes hands. And the original team spends more energy defending their decisions than helping the new team succeed. This pattern is common. It is also entirely avoidable.

Jun 1, 202619 min read

Nobody Talks About On-Call Until the Engineer Has Already Left

On-call culture is the most normalized form of professional self-destruction in the software industry. Engineers accept it because everyone accepts it. Organizations celebrate it because it is cheaper than fixing the systems that require it. And the conversation about whether it is sustainable almost never happens until the engineer is already gone.

Jun 1, 202613 min read

Technical Debt Is a Lie We Tell Ourselves

Technical debt is the most overused, most misunderstood, and most conveniently abused concept in software engineering. It was invented to describe intentional trade-offs made with clear awareness. It has become the universal excuse for poor decisions, accumulated negligence, and the consequences of years of shipping without thinking. There is a difference between debt and damage, and most codebases have the second one.

Jun 1, 202612 min read