Skip to content
5 min read

Code Reviews, Quality, and All the Ways We Screw It Up

Code quality isn’t about nitpicking style or chasing 100% test coverage—it’s about habits. Small PRs, constructive feedback, shared ownership, and learning from mistakes turn quality from a buzzword into a culture teams actually live by.

Code Reviews, Quality, and All the Ways We Screw It Up

Everyone loves to talk about “quality.” It’s one of those words that gets tossed around in kickoff meetings and strategy docs like it’s obvious what it means. But when you actually sit down with engineers and ask, you get wildly different answers.

One person thinks it means zero bugs in production. Another thinks it means code that’s easy to read. Someone else swears it’s about test coverage. Then there’s the person who just wants it to be easy to onboard new hires.

They’re all right. And that’s the problem. “Quality” is a moving target.

What I’ve learned is that quality isn’t something you get by decree. You don’t just say “We care about quality” and magically end up with a clean codebase. It’s something you build into your team’s habits - how you write, review, and ship code, and how you deal with screwups when (not if) they happen.

Automate the Bikeshedding

I once spent 15 minutes in a review arguing about whether snake_case or camelCase should be used for a local variable. The PR wasn’t even that interesting - it was fixing a bug in a log parser - but we were deep in the weeds debating naming like it was a philosophy seminar.

That was the moment I realised: people should not be wasting oxygen on this.

This is why linters and formatters exist. Let them be the bad cops. Humans should focus on whether the code makes sense, not whether it’s indented correctly.

If you’re in JavaScript, lean on Prettier and ESLint. Don’t invent a whole new style guide unless you want future engineers cursing your name in Slack. And if you do deviate, document why. “Because I said so” doesn’t cut it when a new hire has no idea why your project bans default exports.

The best teams I’ve worked with had their CI set up so if your PR failed linting, it didn’t even get reviewed. End of story. It sounds harsh, but it saves hours of nitpicking and keeps reviews focused on what matters.

The Curse of the Monster PR

Here’s a story: one Friday afternoon, a teammate dropped a PR that was nearly 2,500 lines. A new feature and a major refactor, rolled into one. Nobody wanted to touch it. Reviewers skimmed, left a couple of half-hearted comments, and rubber-stamped it.

Guess what happened the next Monday? Production broke. The bug wasn’t subtle either - it was buried somewhere in the 2,500 lines of “trust me, it works.”

Since then, I’ve been ruthless about PR size. Small PRs get reviewed quickly, merged quickly, and if something goes wrong, they’re easy to roll back. Large PRs rot in limbo or worse, slip through with hidden landmines.

So: one logical change per PR. Add a feature, or clean up a function, or refactor an interface - not all three. If you need to make a monster change, break it into stacked PRs. Your future self (and your teammates) will thank you.

Checklists Are Your Friend

Reviews are exhausting. If you’ve been cranking out features all day and someone throws a PR at you, it’s way too easy to glance at the diff, nod, and hit approve.

That’s how things slip through the cracks.

The teams I’ve seen succeed use checklists. Not long, bureaucratic ones - just a handful of prompts:

  • Does this match our architecture patterns?

  • Are there tests? Do they cover the edges?

  • Any obvious performance issues?

  • Security landmines?

  • Enough logging and metrics to debug later?

I once caught a major security flaw because of a checklist. A teammate had added logging… but was logging user passwords in plain text. Easy to miss if you’re skimming. The checklist forced me to stop and ask, “Wait, how are secrets handled here?” That one line item saved us from a nightmare.

Feedback Without Ego

If you’ve ever gotten a review that felt like an attack, you know how demoralising it can be. I had a reviewer once leave comments like “This is garbage” and “Rewrite this, it’s wrong.” They weren’t wrong about the code needing improvement - but the way it was delivered made me dread pushing anything else.

The best reviewers I’ve worked with do the opposite. They treat reviews as collaboration, not judgment. They’ll say things like, “I had a hard time following this loop - could we simplify or add a comment?” Or, “What if we tried this other pattern to reduce complexity?”

It’s not about sugarcoating. It’s about keeping the focus on the code, not the person. If you destroy someone’s confidence, you don’t just slow them down - you slow the whole team.

Don’t Hoard Knowledge

There’s a dangerous pattern where one person becomes the owner of a module. They’re the only one who knows how it works, so every change goes through them. At first, it feels efficient. Over time, it becomes a single point of failure.

I was on a team once where the only person who understood a critical service went on vacation. Of course, that was the week it blew up. The rest of us were flying blind because all the knowledge was locked in their head. We eventually fixed it, but it was painful and avoidable.

The fix is simple: rotate reviewers. Have people outside the “home team” of a module review changes. Let junior engineers shadow reviews and gradually step up. Build buddy systems so knowledge gets spread around.

A healthy codebase is one where no single person is a bottleneck.

Mistakes Are Gold (If You Treat Them Right)

Stuff will break. Deploys will fail. Bugs will sneak past reviews. What matters is how you respond.

The worst thing you can do is start pointing fingers. I’ve seen teams spend more time arguing about who caused the outage than actually fixing it. That’s a culture killer.

The best teams run blameless postmortems. They ask:

  • How did our process let this happen?

  • Where was the gap in our testing, logging, or review?

  • What do we need to change so it doesn’t happen again?

I’ll never forget one outage we had that took down a core service for hours. The root cause wasn’t that someone “screwed up” - it was that our system made it way too easy to screw up silently. Once we reframed it like that, we fixed the system, not the person.

Same goes for retros. The most productive ones aren’t just “what went well, what didn’t.” They’re about experimenting: trying new review habits, new testing practices, new tooling, and seeing what sticks.

And when you ship something? Don’t treat it as “done.” Treat it as a hypothesis. Measure the impact, adjust, and move forward. Some experiments win, some fail - but both are learning.

Closing Thought

Code quality isn’t about pedantic style wars or chasing arbitrary metrics. It’s about building habits where:

  • Tools handle the trivial stuff.

  • PRs stay small and reviewable.

  • Feedback is constructive.

  • Knowledge is shared.

  • Mistakes become lessons, not weapons.

If you get those right, quality stops being a buzzword. It becomes the default. Not because someone said so, but because the team wouldn’t work any other way.