How to Give Technical Feedback in English: Code Reviews and PR Comments
Master the language of code review feedback in English — constructive criticism patterns, softening phrases, and direct comment structures for PR comments.
Giving technical feedback is one of the most sensitive communication skills in software development. Done well, a code review comment builds the team’s knowledge and improves the codebase. Done poorly, it damages relationships and creates a culture of defensiveness.
For non-native English speakers, the challenge is doubled: you need to communicate a technical judgement and calibrate the right tone — not too harsh, not so soft that the message is lost.
This guide gives you the exact patterns, phrases, and structures you need to write and speak technical feedback in English with precision and professionalism.
Why Tone Matters as Much as Content
In many technical cultures — especially in English-speaking companies and international open source projects — how you say something is as important as what you say. A comment like "This is wrong" is technically correct but socially destructive. The same technical observation can be rewritten as:
“This approach could cause a race condition under concurrent load — would it work to add a mutex here, or is there a design you had in mind for handling that?”
Same content. Very different impact.
The Two Failure Modes
- Too harsh: Direct criticism of the person rather than the code. Creates defensiveness, discourages asking questions.
- Too soft: So hedged that the reviewer’s concern is invisible. The author merges the PR without understanding the problem.
Your goal is to be clear, specific, and kind — all three at once.
The Anatomy of a Good Review Comment
Every strong code review comment has these elements:
- Observation — what you noticed
- Concern or reasoning — why it matters
- Suggestion — what you propose instead (or a question to explore alternatives)
- (Optional) Acknowledgement — recognising constraints or alternative views
Template
“[Observation]. [Concern]. [Suggestion/Question].”
Example:
“I see we’re loading all user records into memory before filtering. For small datasets this is fine, but at scale this could exhaust heap — would it be feasible to push the filter into the SQL query instead?”
Softening Language for Code Reviews
Hedging the Observation
Instead of stating a problem as absolute fact, frame it as something you noticed or your perspective:
| Harsh | Softened |
|---|---|
| ”This is wrong." | "I think this might cause issues because…" |
| "You’re not handling errors." | "It looks like the error case isn’t handled here — what’s the intended behaviour if X fails?" |
| "This code is unreadable." | "I’m finding it a bit hard to follow the flow here — would it help to extract this into a named function?” |
Asking Questions Instead of Giving Orders
Questions are powerful in reviews because they:
- Invite the author to share their reasoning
- Leave room for you to be wrong
- Feel collaborative rather than dictatorial
Command: "Move this logic to a service layer."
Question: "Could this logic live in a service layer? It might make the controller easier to test."
Genuinely curious question: "I haven't seen this pattern before — is there a specific reason for using a factory here rather than direct instantiation?"
The “Nit” Label
In many English-speaking teams, reviewers prefix minor, optional suggestions with nit: (short for “nitpick”):
nit: Variable namedatais a bit generic — something likeuserRecordswould make the intent clearer.
This signals: “I noticed this, it’s worth considering, but it’s not a blocker.” It keeps review comments proportionate.
Constructive Criticism Patterns
Pattern 1: “This works, but…”
Acknowledge what the current code does correctly before raising the concern.
“This works correctly for the happy path. However, if the API returns a 429, we’d silently swallow the error — should we add a retry with backoff or at least log and surface it?”
Pattern 2: The “Have you considered…?” opener
“Have you considered using
Promise.allSettledhere instead ofPromise.all? If one request fails, the current code rejects the whole batch — allSettled would let us handle partial failures.”
Pattern 3: Separating observation from recommendation
“I notice the migration runs without a transaction. I’d suggest wrapping it in one — that way if anything fails mid-migration, we get a clean rollback rather than a partially migrated state.”
Pattern 4: Offering to help
“This is a tricky bit of concurrency logic. I’m happy to pair on this if it would be useful.”
Pattern 5: The optional suggestion
“Not a blocker at all, but you might want to consider caching the result here — this function is called in a tight loop in the rendering path.”
Phrases for Common Review Scenarios
Pointing out a Bug
- “I believe this will throw a NullPointerException when
useris null — can we add a guard clause?” - “This condition looks inverted — when
isEnabledis false, the block still runs.” - “The test is asserting the wrong value here — it always passes because it’s comparing
resultto itself.”
Requesting Clarification
- “Could you add a comment explaining why this particular timeout value was chosen?”
- “I’m not sure I follow the logic in this block — could you walk me through what you’re trying to accomplish?”
- “What’s the expected behaviour here when the list is empty?”
Praising Good Work
Reviews should not be purely critical. Calling out good decisions builds trust and reinforces positive patterns:
- “Nice use of the strategy pattern here — this makes it really easy to swap implementations.”
- “Good catch on the edge case — I hadn’t thought about the empty string input.”
- “Clean solution. Much simpler than what I would have done.”
Approving with Notes
When you approve a PR but have minor suggestions:
“Approving — the logic is solid. Left a couple of nits below, but feel free to address them in a follow-up if you’d prefer to merge now.”
Verbal Feedback in Review Sessions
Sometimes code reviews happen synchronously — in a meeting, during pair programming, or over a call. The same principles apply, but pacing is important.
Opening the Conversation
- “I had a look at your PR — overall it looks great. I had one question about the database query on line 47…”
- “Thanks for the thorough description in the PR body — that really helped me understand the context.”
Delivering a Concern Verbally
Slow down for important points. Use a clear structure:
- Signal that you have a concern: “There’s one thing I wanted to flag…”
- Describe it concisely: “The session token is being stored in localStorage, which makes it accessible to JavaScript — that’s an XSS risk.”
- Propose: “Would it be worth moving to an HttpOnly cookie? I can send you an example.”
- Invite response: “What do you think? Does that work with how the auth flow is set up?”
Closing the Feedback Loop
- “Does that make sense, or would it help to go through it together?”
- “Let me know if I’ve misunderstood the context — I might be missing something.”
- “Happy to take another look once you’ve had a chance to revise.”
Key Takeaways
- Good feedback is clear, specific, and kind — all three at once, not trading one for another.
- Frame criticism as observation + concern + suggestion, not as a verdict on the author.
- Use questions to invite dialogue and leave room for the author’s reasoning.
- “Nit:” is a useful signal for optional, non-blocking suggestions.
- Praise good decisions — positive feedback is as valuable as criticism.
- In verbal reviews, slow down for important concerns and always invite a response.
- End with an open door: “Let me know if anything is unclear” keeps the conversation collaborative.
Code review is a team sport. The language you use shapes the culture of your team — one comment at a time.