Picture this: You've been grinding on a tricky problem for days. The bug was more elusive than you expected, the troubleshooting took way longer than you hoped, and you've been living in this code for what feels like forever. But you finally got it. You've tested it, cleaned it up, and you're satisfied with the solution. You submit your PR (pull request), feeling that small rush of accomplishment - you're done.
Then the code review comes back.
Some nitpicky comment about formatting. Or worse - a "suggestion" to fix something completely unrelated to your changes. Something that was already broken. Something that has nothing to do with the problem you just spent days solving.
And just like that, you're dragged back into that pain-in-the-ass ticket you thought you'd finished. That feeling of accomplishment? Gone. The momentum you had to tackle the next thing? Dead. Instead, you're annoyed, frustrated, and wondering why the hell this couldn't have been handled differently.
This is what happens when code reviews prioritize technical perfection over people.
The False Choice
Here's the lie we've been sold: that caring about code quality and caring about your teammates are somehow in tension. That to maintain high standards, you need to be ruthlessly critical. That being a "good" reviewer means catching every possible issue, regardless of scope, regardless of impact, regardless of how it affects the person on the other end.
Bullshit.
Some reviewers genuinely have good intentions - they're just really bad, unthoughtful communicators. But that's not okay. They need to be better. They need to care about how they're coming across and how others are going to feel about what they say. Being technically right doesn't give you a pass to be a shitty teammate.
What's Actually at Stake
There's been a lot of talk lately about "psychological safety" in tech teams, and code reviews are one of the places where it matters most. People do their best work when they feel safe and comfortable with their team. There's nothing better than knowing the people you're working with are going to help you succeed, not tear you down or pile on unnecessary work.
When code reviews become a place of nitpicking, scope creep, and technical gatekeeping, you destroy that safety. You erode trust. You kill morale. You slow down velocity. You turn what should be a collaborative process into something people dread.
And for what? So you can feel smart? So you can be "right"? So you can prove you caught something?
You can have something great. Why would you fuck that up?
What This Article Is Really About
Code review isn't really about the code - or at least, it's not just about the code. It's a vehicle for teamwork. It's one of the best opportunities we have to collaborate, share knowledge, and help each other grow.
This article is about how to think about code reviews differently. How to be technically rigorous without being an asshole. How to maintain high standards while building people up instead of tearing them down. How to make code review one of the strongest parts of your team culture instead of one of the most toxic.
Because the best code reviews don't force you to choose between quality and humanity. They recognize that both matter, and they're better when you get both right.
Framework: Block vs. Observe vs. Track
Not all code review feedback is created equal, and treating everything as a blocking issue is one of the fastest ways to kill team morale and slow down delivery. Here's a simple framework for categorizing your feedback:
Block (Must fix before merge)
These are issues that genuinely cannot go into the codebase as-is:
- Security vulnerabilities - anything that creates a security risk
- Breaks existing functionality - regressions or bugs introduced by the changes
- Critical logic issues - overly complicated logic that should be refactored, code that doesn't actually solve the problem it's meant to solve
- Violates essential project standards - things your team has explicitly agreed are non-negotiable
If you're blocking a PR, the issue should be clear, significant, and directly related to the changes being made.
Observe (Comment, but don't block)
These are suggestions or observations that might improve the code but aren't critical:
- Minor improvements - "Not critical to change, but if you agree this would be an improvement and you have time for it, consider X"
- Learning opportunities - sharing knowledge or alternative approaches without demanding changes
- Clarifying questions - "Help me understand why you chose this approach?" (genuine curiosity, not passive-aggressive criticism)
What NOT to do: Don't comment just because "I might have done it differently." If it doesn't violate good principles, practices, or project standards, and you just would have made a slightly different choice? Keep that to yourself. Your personal preference isn't a valid reason to slow someone down.
Track (Create a separate ticket, don't block the PR)
This is the category that causes the most problems, and it's simple: If this PR didn't break it, this PR shouldn't have to fix it.
Any time you discover a bug or issue while reviewing code that was NOT caused by the developer's changes, that's a tracking issue:
- Pre-existing bugs you notice while reading the surrounding code
- Technical debt or refactoring opportunities in adjacent code
- Broader architectural concerns
- Missing test coverage in existing code
How to handle this: If you spot an out-of-scope bug, YOU handle it. Make a note, create a ticket, bring it up in standup - whatever you want. But it's downright rude to dump that work onto someone else when they're at the code review stage. They think they're done with their task. Unrelated scope or bugs are not their domain unless they caused them with their changes.
Why scope respect matters: The whole idea of agile development is getting shit done. When you continually add work to each step, you fuck up the whole system. That task suddenly takes an extra hour, now the developer can't get to their next task, now they can't complete what they committed to, and your sprint could easily get derailed. Moving fast and getting tasks accomplished feels fulfilling. Sitting on one task fixing extra bullshit feels bad.
The testing question: If it's not in the specs of the ticket, how is it going to be tested? Any bugs or issues that are significant need to be tickets and go through the normal process (design/dev/qa/whatever). A very small amount of boy-scouting is appreciated and good, but anything extensive needs proper planning.
The rare exception: Look, if something is going to literally cause the system to be seriously broken, and you genuinely don't have time to deal with it yourself, it's not the end of the world to ask the author for help. But if that's the case, acknowledge it for what it is: asking for help, outside of the norm. Make it crystal clear this is an exception, acknowledge that this isn't an issue with what the coder did, and be kind and sensitive to their feelings. Don't make exceptions often - that's how exceptions become the rule.
Making Code Reviews Work
Code review is about many things - ensuring quality, catching bugs, sharing knowledge, maintaining standards. But here's what matters most: Your primary job as a reviewer is to help the person who submitted the code.
Yes, you have a responsibility to protect the codebase and make sure everything that gets merged makes the project better. But it's so much more important to help the developer be the best they can be.
The Reviewer's Responsibilities
The core mindset: Humility and care. You need to be humble and not act like you know for sure that what you see or think is definitely right. Obviously, you need to express your thoughts and concerns - that's the whole point - but do it in a way that acknowledges your own fallibility. This goes a long way in preventing the author from thinking you're just an asshole.
Approach every code review from the place of a helpful friend or colleague who wants the best for the author. You should care about the project, but you also need to care about and root for the person. You want them to succeed and do their best work.
Communication that helps, not harms. Assume the best of the coder and their code. Don't say stupid shit like "that's kind of a mess isn't it." Be kind and clear. Helpful feedback helps the author complete their task in the best and most efficient way. Criticism for criticism's sake has almost no place in code reviews.
Questions can work, but use them carefully. Some reviewers use questions that come across as obnoxious or condescending rather than genuinely curious. If you really have questions about the approach or reasoning, sometimes a private Slack chat is better than cluttering the PR with "why did you do it this way?" comments that feel like attacks.
Balancing technical standards and team health. Here's the thing: You can't accomplish anything if you fuck up the team. You have to get people working toward the same goals. You need to work together to be your best.
You absolutely can maintain high technical standards while caring about your teammates - in fact, that's the only way to maintain them long-term. If someone doesn't know or understand something, help them. But you can't do it while only caring about the task or the project. Do it with genuine care for the individual and their growth.
I can't imagine many people who wouldn't appreciate that kind of genuine help. But if you don't give a shit and just want the project done? You suck. Go fuck yourself.
While you all have to care about the goals, to be a team, you have to give a shit about each other more.
Before you hit submit: The self-check. Ask yourself these questions before submitting your review:
- Is this necessary? Does this feedback actually need to be said?
- Am I sure this is the problem I thought it was? Have I checked my assumptions?
- If I got this comment, would I be upset? Put yourself in their shoes
- Is this going to help and lift up the author? Is this feedback in service of their growth?
- Can I say it in a way that's kind and helpful? How can I phrase this better?
What great looks like. The best code reviews come from a place of genuine care. You can feel it coming through in the comments. The reviewer cares about the project, but they're also clearly rooting for you. They want you to succeed and do your best work.
If you're going to focus on one thing as a reviewer, focus on lifting people up. Share what you know with the purpose of helping, not showing off or asserting dominance.
The Author's Responsibilities
Code review isn't just about reviewers doing their job well - authors have responsibilities too. Be open to feedback. Put yourself in the shoes of the reviewer and assume the best of them. Give them the benefit of the doubt and default to making the requested change even if you don't fully agree. Unless it's genuinely a terrible suggestion, it's better for the team to just make the change and move forward.
Make reviews easier. Keep your PRs small. If someone's reviewing multiple pages of code, something went wrong. Write helpful descriptions, especially if it's not clear why something was done a certain way. But the best approach is writing solid, self-explanatory code that doesn't need much explanation.
When your team lacks good norms. If your team doesn't have good code review practices, you can try addressing it directly with individuals, hoping they'll want to do better. But if that doesn't work and the behavior continues - especially if it's affecting other developers too - you should probably escalate it. Taking issues to a manager or team lead isn't about being a snitch. It's about protecting the team's health and productivity.
What Good Looks Like
Good code reviews don't just catch problems - they make you better at your craft and strengthen your team. Here's what that actually looks like in practice.
Example: Genuine, Helpful Feedback
Let's say you're working on a feature and the controller method keeps growing. You're focused on solving the problem, so you don't realize when it's time to step back and refactor. A good reviewer might say something like:
"This works well! One thought - this method is getting pretty long. It might be nice to refactor this section into a separate method (maybe in the model?). I think it would help with readability. What do you think?"
What makes this work:
- It acknowledges the code works
- It frames the suggestion as a thought, not a demand
- It explains the benefit (readability)
- It's collaborative ("What do you think?")
- Most importantly, it feels genuine and helpful, not malicious
It's hard to explain exactly why or how you can tell when feedback is genuine, but it definitely bleeds through in how it's phrased. You can feel when someone is trying to help you vs. when they're trying to prove they're smarter than you.
Example: Handling Out-of-Scope Issues the Right Way
Here's a scenario that happens all the time: You're reviewing a PR and you notice a bug in the surrounding code - something that has nothing to do with the changes being made. Here's how to handle it:
During the review: You make a quick note in your notebook or a scratch pad - "Found potential issue with input validation on line 247."
In standup: You bring it up: "Hey, while reviewing Noah's PR, I noticed we might have an input validation issue in the FilterForm class. Is that a known issue?"
Why this matters: Someone might say, "Oh yeah, I've actually seen that too - I'll add a bug ticket for it." Or they might say, "Yeah, Sarah's already working on that." You don't know what other work is in progress, and adding scope to someone's PR could literally duplicate work that's already being done.
After verifying it's not known: You (or someone else) creates a proper bug ticket and it goes through the normal process - prioritization, assignment, testing, the works.
In the PR: You don't mention it at all, or at most you drop a quick note: "Noticed a small issue in adjacent code - created ticket #1234 to track separately. Nice work on this fix!"
The PR author never has to deal with it. You took responsibility for the discovery and handled it appropriately.
How Good Reviews Feel
After a good code review, you might still feel a little bad if you missed something - nobody likes realizing they made a mistake. But overall, you're glad the issue was caught. You might even take a note about something to watch out for next time.
Most importantly, you feel like your teammate was looking out for you. Not trying to catch you, not trying to show you up, but genuinely helping you succeed. That feeling is everything.
Good code reviews leave you feeling supported, not attacked. They make you better without making you feel worse.
The Bottom Line
Here's what it comes down to: Your team matters more than any individual project or sprint.
Sprints come and go. Tickets get completed and forgotten. But if you're draining your team's motivation and trust for the sake of catching every possible issue, you're optimizing for the wrong thing. If you make your team stronger with each sprint, that compounds. If you erode trust with each code review, that compounds too - just in the wrong direction.
The good news? It doesn't take much to be better. It takes giving a shit about your teammates. It takes a moment of reflection before you hit submit on that review. It takes recognizing that the person on the other end of that PR is a human being who's trying their best.
Don't be an asshole. That's really the core of it.
Take some time to reflect on your own code review practices - both as a reviewer and as an author. Better yet, ask your team how they feel about the code reviews that have been happening. You might be surprised by what you hear.
Code reviews can be one of the best parts of working on a team, or one of the worst. The choice is yours.