Essay

Code Review as Teaching

The best code reviews transfer knowledge, not just catch bugs.

Swati S.

Code review is not quality control. It's knowledge transfer. Every comment is a teaching moment. Every approval is a lesson. The code you review today becomes the code someone else writes tomorrow.

I've seen teams where code reviews were weapons. Engineers left comments like "this is wrong" without explanation. The result? Junior engineers learned to fear reviews, not learn from them. They'd make the minimal change to get approval, not improve their understanding.

The best code reviews I've received weren't about catching bugs—they were about teaching thinking. The reviewer explained why a change mattered, what edge cases I'd missed, what patterns I could apply elsewhere. I learned more from those reviews than from any tutorial.

Start from a place of curiosity. "I see you did X. Help me understand why." Assume good intent. Assume they know something you don't. Your job is to understand, then guide.

Explain the why, not just the what

Don't just say "this is wrong." Explain why it's wrong. What will break? What edge case will fail? What pattern will it encourage others to copy?

# Instead of: "Use a dictionary here"
# Say: "A dictionary gives O(1) lookups. With 1000 items, this list 
# search will be O(n) and could become a bottleneck. If this grows 
# to 10,000 items, it will be slow. Use a dictionary for constant-time lookups."

# Bad
items = [item for item in items if item.id == target_id]

# Better
items_dict = {item.id: item for item in items}
target = items_dict.get(target_id)

The first comment fixes one line. The second comment prevents a class of mistakes. It teaches performance thinking, not just syntax.

I once left a comment that just said "use a set instead of a list." The engineer changed it, but they didn't understand why. The next week, they made the same mistake in a different place. If I had explained why sets have O(1) membership checks while lists have O(n), they would have understood the pattern, not just memorized the fix.

Point to patterns, not just problems

When you see a problem, ask: "Does this pattern exist elsewhere?" Don't just fix the instance. Fix the pattern. Document it. Share it in team notes.

If you find the same issue in three places, that's a pattern. Patterns need pattern solutions: a helper function, a shared component, a design guideline.

I once reviewed code that used string concatenation for building URLs in five different places. Instead of fixing each instance, I suggested a helper function. The next week, two engineers used that helper function in new code. The pattern solution taught the pattern.

Patterns also need pattern prevention. When you see a common mistake, document it. Add it to your team's "common pitfalls" list. Share it in a team meeting. Help others avoid it before they make it.

Review architecture, not just syntax

Syntactic errors are easy to catch. Architectural problems are harder. Ask:

  • Does this fit the existing patterns?
  • Will this scale with our expected growth?
  • What happens when we need to change this?
  • Does this create coupling we'll regret later?

These questions teach thinking, not just coding.

I once reviewed code that solved the immediate problem but created tight coupling. I asked: "What if we need to change the data source?" The engineer said: "We'll change it then." I asked: "How many places would you need to change?" They counted: seven. That question taught them to think about future flexibility, not just current correctness.

Architectural reviews are harder because they require judgment, not just knowledge. But they're more valuable because they teach judgment, not just syntax.

Suggest alternatives, don't just reject

Instead of "this won't work," say "here's another approach." Offer options. Explain trade-offs. Let them choose, but make the choice informed.

# Current approach (works, but might be slow for high volume)
# Alternative 1: Use a queue (better for high volume, adds complexity)
# Alternative 2: Use a database (better for persistence, adds latency)
# Alternative 3: Use a cache (better for speed, loses data on restart)
# 
# For this use case, I'd recommend Alternative 1 because we expect 
# high volume and can tolerate added complexity.

Teaching means giving tools, not just answers. When you suggest alternatives, you teach trade-off thinking, not just syntax.

Celebrate good patterns

Not all reviews are corrections. When you see good code, say why it's good. "I like how you handled the edge case here." "This abstraction will make testing easier." "This pattern will scale well."

Positive feedback reinforces good practices. It also builds trust. Reviews shouldn't feel like criticism. They should feel like collaboration.

I make it a point to leave at least one positive comment in every review. Even if the code needs significant changes, find something good. It could be clear naming, good error handling, or thoughtful comments. Positive feedback makes critical feedback easier to accept.

Review in context

Understand what the change is trying to accomplish. A hack in a hotfix is different from a hack in a feature. A quick solution to unblock testing is different from production code.

Provide feedback that fits the context. Emergency fixes get different standards than new features. Teaching means knowing when rules apply and when they don't.

I once reviewed an emergency hotfix where the engineer used a quick workaround. I could have suggested a cleaner solution, but the context was: users are down, we need a fix now. I approved the workaround and suggested we file a ticket to refactor it later. Teaching means understanding context, not just applying rules.

Make reviews a conversation

The best reviews happen in dialogue. Ask questions. Listen to answers. Iterate on solutions. Don't just leave comments and walk away. Engage.

I've had reviews where we went back and forth four times, each iteration improving the solution. By the end, both of us learned something. The engineer learned about the pattern. I learned about their reasoning. Good reviews are conversations, not monologues.

Review the design, not just the implementation

Code review isn't just about the code—it's about the design. Ask:

  • Is this the right solution to the problem?
  • Are there simpler alternatives?
  • Does this create technical debt?
  • Will this be maintainable in six months?

These questions teach design thinking, not just implementation skills.

I once reviewed code that solved a problem correctly, but in a complex way. I asked: "What problem are you trying to solve?" They explained. I asked: "Could we solve it more simply?" They thought about it. The next iteration was much simpler. The question taught them to think about simplicity, not just correctness.

Use reviews to teach judgment

Code review is where judgment gets developed. When should you optimize? When should you keep it simple? When should you add abstraction? When should you avoid it?

These aren't questions with right answers—they're questions of judgment. Good code reviews help develop that judgment by explaining the reasoning behind recommendations.

I try to explain my reasoning in reviews. "I'm suggesting this pattern because we'll likely need to extend it later." "I'm avoiding this abstraction because it's premature." Those explanations teach judgment, not just rules.

Review with empathy

Remember what it's like to be on the receiving end. Put yourself in their shoes. How would you want feedback? What would help you learn?

I try to frame comments as questions when possible. "Have you considered X?" instead of "You should do X." Questions invite dialogue. Commands invite defensiveness.

Also, recognize that everyone makes mistakes. A code review isn't a judgment of character—it's a learning opportunity. Treat it that way.

Measure review quality by learning

Good code reviews result in better code, yes. But they also result in better engineers. The junior engineer who learns from your review will write better code next time. The senior engineer who learns from your review will review better code next time.

Measure review quality by what people learn, not just by what bugs you catch. If engineers are making the same mistakes after your reviews, your reviews aren't teaching effectively.

Code review is teaching. Teaching requires patience, clarity, and empathy. Review the code, but teach the engineer. That's how teams get better.


About the author

Swati S. helps you master system design with patience. We believe in curiosity-led engineering, reflective writing, and designing systems that make future changes feel calm.