The rules that still hold
Meaningful names. This is the rule I still enforce hardest in code review. getUserById beats getById, pendingInvoices beats list. Names are the most-read, least-edited part of code. Getting them right pays dividends every time anyone reads the file.
Functions should do one thing. Holds up. A function that parses input, mutates state, and logs is three functions pretending to be one. Refactoring toward single responsibility almost always makes code easier to test.
Don't repeat yourself — in spirit. The principle is sound. The execution, in the book, gets overzealous (more on that below).
Error handling is a first-class concern. The chapter on exceptions vs. error codes still reads well. Whether you use exceptions or Result types, treating errors as designed-for — not an afterthought — is correct.
The rules that have aged badly
"Functions should be 4 lines or less." This was always a bad rule. Taken literally, you end up with twenty one-line functions that each call the next. You have to chase the definitions across the file to understand what the code does. The stated intent (small, focused functions) is good. The prescription produces worse code than it prevents.
Readable size is context-dependent. A 40-line function that tells a clear story is often better than 10 four-line functions with generic names.
DRY applied dogmatically. The book treats any code duplication as a sin. Experience has taught me the opposite: premature deduplication is worse than duplication. Three similar-looking sections of code are often not the same concept — they just share a shape today. Extracting a shared abstraction locks them together. When one needs to change, you either contort the abstraction or rip it out.
The modern phrasing: prefer duplication to the wrong abstraction. Deduplicate when the abstraction is obvious and stable, not at first sight of pattern.
Comments as code smells. The book is hostile to comments. Some comments are smells (restating what the code says). But the book's influence meant a generation of developers aggressively stripped comments that actually belonged — the ones explaining why a line is unusual, or documenting a workaround for a specific bug. Good comments are rare because they take judgment to write, not because they are intrinsically bad.
Single-letter and abstract naming for "clarity." The book's long-function-as-an-object-decomposition examples push toward a style where concepts are spread across tiny objects with abstract names. It looks clean on the page and reads miserably in a real codebase. The React-era lesson — colocate related logic — points the other way.
The meta-lesson
Clean Code has a style. It is not universal. Following the book to the letter produces Java-flavored code with lots of small classes and Gang-of-Four patterns. That style is fine for some projects and actively harmful for others (JavaScript, Go, anything embracing functional composition).
The durable wisdom in the book is about caring — that code is read far more than it is written, that naming matters, that duplication needs judgment. The dated wisdom is the specific prescriptions.
What I tell juniors now
Read it once. Extract the principles, not the rules. When your judgment disagrees with a specific recommendation, trust your judgment and the context you have. The book is a reference point, not a rulebook. A senior engineer who has read Clean Code, disagreed with half of it, and kept reading is better off than one who took every chapter as gospel.
