Code review people don't dread
Published June 6, 2026 · by Majd Ghithan, written with the help of AI
I once left forty-one comments on a junior's pull request. I was proud of it. Thorough, I told myself. The next day he barely made eye contact, and his next PR sat open for a week because he was terrified to hand it to me again. I had reviewed the code perfectly and broken the person.
That's the thing nobody tells you about review: the code is the easy part. The hard part is that a review is a message from you to another human, and they read the tone before they read the logic.
Here's how I do it now.
Separate the nit from the blocker
Most of what I want to say on a PR doesn't actually block the merge. A variable name I'd have picked differently, a helper that could be extracted later, a test I'd have written slightly cleaner. Real, but not worth holding the branch hostage over.
So I label. If a comment starts with nit:, it means "take it or leave it, I won't re-request changes over this." If it doesn't have a prefix, it's a real blocker and I say why it blocks. That one convention changed my reviews more than anything else. The author instantly knows what they have to deal with versus what's just my taste.
Tone is not a soft skill, it's the whole message
A review comment has two jobs: fix the code, and keep the person willing to write more code. You can nail the first and fail the second, and then it doesn't matter how right you were.
The difference is usually one small rewrite. "Change this" is an order handed down. "Here's why" is two engineers looking at the same problem. Same fix, completely different thing to receive.
This is wrong. Don't query inside the loop.
This runs a query per iteration - it'll be an N+1 once orders grows. Eager-load with with('customer') above the loop and it drops to one query. Same bug bit me last quarter.
The right-hand one is longer, and it's worth every character. It names the problem, explains the why, hands over the fix, and quietly says "I've made this mistake too." Nobody feels stupid reading that. They feel like they just got let in on something.
"Here's why" beats "change this" every time
If I can't explain why a change matters, maybe it doesn't. Forcing myself to write the reason is also a filter on my own comments. Half the time I start typing "you should…", hit the "because…" part, and realize my reason is just "it's how I'd do it." That comment doesn't get posted.
When the reason is real, the author gets a lesson they carry to the next PR. When it isn't, I've saved us both a pointless thread. Either way, writing the why makes the review shorter over time, because people stop repeating the mistakes you actually explained.
Async review is a feature, not a downgrade
I don't need to sit next to someone to review their code, and honestly I review better when I don't. Async means the author isn't watching my face while I read, so they're not defending in real time, and I'm not performing thoroughness. They get my comments, they sit with them, they push back on the ones I got wrong.
The rule that makes async work: a review is a conversation with a clear end. I don't leave forty-one open threads. I leave the blockers, a couple of nit:s, and one line at the top that says the verdict, "two real things to fix, rest is optional, ping me when it's ready." The author knows exactly what "done" looks like.
The approval is part of the review too
I used to only speak up when something was wrong, which trained everyone to read my name in the reviewer list as bad news. Now if someone solved a gnarly problem cleanly, I say so, right there on the line. It costs me five seconds and it buys something real: the next time I leave a blocker, they know I'm not just hunting for faults. I'm reading the whole thing, the good parts included.
The point
A review isn't a gate you stand at to keep bad code out. It's the main way your team learns from each other, and the main way trust either builds or erodes, one comment at a time.
Get the code right, sure. But the code was always going to get fixed. What you're actually deciding, every time you hit "submit review," is whether the person on the other end walks away sharper and still wanting to write code, or quietly starts routing their PRs to literally anyone but you.
