How to Give Code Feedback Without Making It Personal
by Eric Hanson, Backend Developer at Clean Systems Consulting
The Feedback That Landed Wrong
"This is the wrong approach entirely. Why would you use a switch statement here instead of polymorphism? This will be a nightmare to maintain."
The reviewer was right about the technical concern. The code would be harder to maintain. But the feedback was phrased as a judgment — of the decision, of the reasoning, and implicitly of the developer who made it. The author responded defensively. A thread of twelve comments followed, none of which improved the code. The underlying technical issue was eventually addressed in a separate PR with significantly more friction than necessary.
The feedback that is right but lands wrong is worse than no feedback in one specific way: it trains people to be defensive in code review, which makes future reviews less honest.
The Mechanics of Technical Feedback
Good code review feedback shares a structure:
Name the concern, not the person: "This approach will be harder to extend when we add new event types" describes a property of the code. "Why would you do this?" describes the author's judgment. The first invites discussion. The second invites defensiveness.
Explain the reason: Feedback without reasoning is an instruction. Feedback with reasoning is a learning opportunity and opens a genuine conversation. "This switch statement will require modification in multiple places when a new event type is added — a strategy pattern would localize that change" gives the author enough context to evaluate the concern and propose alternatives.
Distinguish severity: Not every comment requires the same response. "This will cause a production bug" is different from "this naming is slightly less clear than it could be." Indicate the difference. Prefixes like [nit], [suggestion], [blocking], or [question] make the priority explicit and prevent authors from spending equal time on a blocking correctness issue and a stylistic preference.
Ask questions instead of making declarations: "Have you considered what happens when the list is empty?" is less confrontational than "This will throw an NPE on an empty list." Both are pointing at the same issue. The question form acknowledges that the author may have already thought about this and invites them to share their reasoning.
Separating the Code From the Person
The phrase "I would have done this differently" is more productive than "this is wrong" even when the second is technically accurate. It acknowledges that reasonable engineers make different choices, opens discussion about alternatives, and doesn't require the author to publicly accept that they were wrong.
This is not softening technical truth. The concern is still on the table. The framing makes it easier to engage with honestly rather than defensively.
Consider:
- "This is a bad design" → "I have a concern about this design — specifically..."
- "This won't scale" → "I'm wondering how this performs at 10x current volume, specifically the query on line 42"
- "You're missing error handling" → "What happens here if the payment API returns a timeout?"
The technical content is identical. The reception is different.
The Positive Comment Problem
Code review cultures that consist entirely of finding problems train reviewers to only look for problems. Authors who receive only critical feedback on every PR eventually experience review as adversarial.
Explicitly noting what is well done is not just politeness. It is useful information: it tells the author which decisions were good, which makes the critical feedback more credible ("this person actually read the code carefully and is telling me the specific thing they think is wrong, not just looking for anything to criticize").
A comment that says "the idempotency key handling here is exactly right, including the double-check after the lock — I've seen this done incorrectly in a lot of codebases" is useful feedback.
The Asynchronous Communication Problem
Code review happens in text. Text strips tone, facial expression, and the rapport that makes in-person technical discussion possible. A comment that would sound like collegial debate in a conversation can read as hostile in a PR thread.
Mitigation strategies:
- For substantial concerns, offer to discuss in a call or over Slack before leaving a long thread of PR comments
- End consequential critical comments with an invitation: "Happy to discuss the tradeoffs if you want to jump on a quick call"
- When you are the recipient of feedback that landed badly, assume good intent and ask a clarifying question before responding defensively
The Practical Takeaway
In your next code review, before submitting any comment, read it aloud and ask: does this comment tell the author what to think about, or does it tell them what to think about themselves? If it's the latter, rewrite it to focus on the code's properties and your concern about them. Then add at least one specific positive comment about something the author did well. This costs thirty seconds and produces a measurably different review experience.