Code review culture
A culture document written in reviewer comments.
Most teams have a wiki page about how they do code review. It says things like "be kind" and "explain your reasoning." Almost nobody reads it after their first week. Every day, people read something else: the comment stream on open pull requests.
That stream is the real culture document. The wiki describes the team you wish you had, and the last fifty review threads describe the team you have: how disagreement gets handled here, whether a question is welcome or treated as an attack, whether good work ever gets named, whether a junior can hold the line against a senior. New hires learn all of this in their first two weeks, from the threads rather than the page.
You can watch it happen. A new engineer joins, reads through a few merged PRs to learn the codebase, and picks up the tone along with the code. Three weeks later their own review comment on a teammate's change is a single word with no explanation: "why?". They are not being rude. They are copying the senior reviewers, whose comments look exactly the same.
As the leader, you are the editor of that document whether you choose to be or not. Every norm in the stream is there because you set it or because you let it stand. You cannot disown it later by pointing at the wiki.
Audit the stream first
Before you rewrite the review guidelines, read the existing threads. Open the last fifty merged PRs and read the comments as if you were a new hire trying to figure out the rules.
You are looking for patterns rather than individual slip-ups:
- Does every approval come with a "looks good" and nothing else, which would mean review is for show and nobody is reading?
- Do certain reviewers redesign every change they touch?
- Are real bugs and style preferences arriving in the same flat tone, so the author cannot tell which is which?
- Is there a reviewer everyone routes around because their threads are exhausting?
The wiki cannot tell you any of this, but fifty threads read in one sitting can. It is a tedious afternoon, and by the end of it you will know exactly where to start.
Label how much each comment matters
When people complain about review, they rarely mean the feedback is harsh. They mean it all sounds the same: a correctness bug and a preference about variable naming show up as two comments in the same thread, in the same flat voice, and the author cannot tell which one they have to fix.
Most teams fix this by labeling each comment by weight: blocking, a suggestion, or a nit. (Nit is a silly word, but every team seems to land on it.) Blocking stops the merge, for a correctness bug or a real design problem. Everything else is non-blocking by default, and the author decides which nits to take before shipping.
Picture the alternative. A PR comes back with fourteen comments, two of them genuine bugs and the other twelve about spacing, naming, and "I would have done this differently." The author cannot tell which of the fourteen matter, and arguing about any of them means a round trip with the person who controls the merge, so they do the safe thing and address all fourteen, rewriting working code to satisfy preferences and maybe adding a new bug along the way. The two real issues carried the same weight as an argument about a variable name.
These labels are not about politeness. The wording of a hard comment is its own skill. They do something narrower: they tell the author what they have to fix and what they can ignore. The labels only work if reviewers honor them, because the first time a nit quietly holds up a release, authors go back to treating every comment as blocking, and the whole scheme becomes decoration.
Hold the bar at code health
Without a clear standard for when to approve, every reviewer falls back on one question: is this how I would have written it? The strongest teams swap that for a less obvious one: approve a change once it makes the codebase better than it was, even when it is not perfect, because nothing ever is and holding out for perfect means nothing ships. When a reviewer's taste runs into a plain fact about the code, the fact wins.
You will have to defend that standard, because one kind of reviewer pushes hard against it: the one who would rebuild every change around a different design.
Say a junior opens a correct, tested change, and a senior reviewer who would have built it around a different abstraction asks for the rewrite. The PR sits for two days while the author redoes something that already worked, and everyone watching learns that being right is not enough here, that you also have to guess the reviewer's taste.
When a reviewer prefers a different design, they can raise it as a follow-up, but it does not block a change that already works. If the change improves the codebase and is not buggy, it ships, and the team can take up the better design on its own. Reviewers can abuse this from the other side too, waving a change through with "improves code health" and never reading it closely, so the standard also depends on reviewers who keep reading.
Hand the machine its arguments
No human should ever write a whole class of review comment: formatting, import order, line length, whitespace, the lint rules, the obvious security scans. A machine should settle all of them, and if two engineers are debating spacing in a thread, the toolchain has a gap that will rerun that debate on every change until somebody closes it.
Push style, linting, and security scanning into automation that runs before a human looks at the change. This does not lower the bar. It points human attention at what only people can judge: the logic, the architecture, the intent, whether the change should exist at all.
You can also trust the toolchain too much. A green linter says nothing about whether the logic is sound, because the machine only owns the arguments that have one correct answer, and judgment was never one of them. A team that forgets the difference will eventually ship a broken feature behind a passing build.
Watch how long changes wait
Watch how long a change waits before anyone looks at it. When a PR sits for a day before its first comment, the author hears that their work does not matter to anyone. The queue rots for an unglamorous reason: a review costs the reviewer focus right now, the waiting costs only the author, and nobody is ever billed for the delay.
Set a norm on response time, and be precise about what it means: you promise to look within a few hours, which is a different promise from approving within a few hours. Looking quickly keeps everyone honest about attention, while promising to approve quickly just pressures everyone to rubber-stamp. Pair it with an expectation about change size, because a review only works if the change is small enough to hold in your head. Then watch how long that first response takes, and when it starts climbing, something is wrong before any other signal shows it.
As more code gets generated, more changes pile into the review queue than ever before. The mechanics of that surge are their own subject. You own the cultural half of it: when the queue is slow, people learn that review does not matter here.
Write the first chapter yourself
You undo all of it the moment you exempt your own code from review. You write the first chapter of the culture document, because everyone watches how the leader behaves in review far more closely than they listen to anything the leader says about it.
Put your own changes through the same review, in the open, with no special lane. Ask instead of command in your comments, because "could we pull this into its own function?" and "pull this into its own function" teach two different cultures. And when someone junior catches a real bug in your code, the team will remember how you respond to it in public.
A junior leaves a comment on your change pointing out a case you missed. You reply in the thread, thank them by name, and ship their fix. Everyone watching just learned that catching the leader is safe, and that the leader answers a catch with thanks rather than a defense.
The reverse corrupts the document fastest: exempt your own code, or argue down every comment on it, and everyone learns that the rules stop one level above them.
What the stream has to stay honest about
When reviewers only ever flag what is wrong, people learn to dread review, because it becomes the place their work goes to get marked up and never praised. So name good work too, and say why: this is a clean abstraction, this test is exactly the one I would have wanted. Skip the empty praise that inflates until it means nothing, and point at something specific that cleared the bar, so the team can see where the bar sits.
The critics of review get something right. It can turn into gatekeeping, a status contest where authors write to please the reviewer instead of improving the code, and the slow back-and-forth eats up everyone's day. Every section above is aimed at that failure. Scrapping review would not make the norms go away, though. It would only take away the one place you can read them. The last fifty threads are sitting in your repository right now, and an afternoon with them will tell you which of these sections your team needs first.