Code Review Practices
This skill provides guidance for conducting effective, constructive code reviews that improve code quality and team collaboration.
Review Mindset
Goals of code review:
-
Catch bugs and issues early
-
Share knowledge across the team
-
Maintain code quality standards
-
Improve code maintainability
-
Foster learning and growth
Not goals:
-
Assert dominance or superiority
-
Enforce personal preferences
-
Block progress unnecessarily
-
Nitpick without value
What to Review
- Correctness
Does the code work as intended?
-
Logic is sound
-
Edge cases are handled
-
Error conditions are managed
-
Requirements are met
- Design and Architecture
Does it fit the system?
-
Follows existing patterns
-
Appropriate abstractions
-
Reasonable complexity
-
Scalable approach
- Readability
Can others understand it?
-
Clear naming
-
Logical organization
-
Appropriate comments
-
Consistent style
- Testing
Is it adequately tested?
-
Tests exist for new code
-
Edge cases covered
-
Tests are maintainable
-
Integration points tested
- Security
Are there security concerns?
-
Input validation
-
Authentication/authorization
-
Sensitive data handling
-
Known vulnerabilities
- Performance
Will it perform well?
-
No obvious bottlenecks
-
Efficient algorithms
-
Resource usage reasonable
-
Scalability considered
Review Process
- Understand Context
Before reviewing code:
-
Read PR description and linked issues
-
Understand the problem being solved
-
Check CI/CD results
-
Note any special considerations
- Review at Appropriate Level
High-level first:
-
Overall approach
-
Architecture decisions
-
Major design choices
Then details:
-
Implementation specifics
-
Edge cases
-
Code style
- Provide Actionable Feedback
Good feedback:
-
Specific and clear
-
Explains the "why"
-
Suggests solutions
-
Prioritizes issues
Example:
Consider using a Set instead of an array here for O(1) lookups. With the current implementation, the nested loop creates O(n²) complexity which could be problematic with large datasets.
- Use Review Comments Effectively
Types of comments:
Blocking (must fix):
-
"This will cause a race condition when..."
-
"Security issue: User input is not sanitized..."
-
"This breaks the API contract by..."
Non-blocking (suggestions):
-
"Consider: This could be simplified by..."
-
"Nit: Variable name could be more descriptive"
-
"Question: Why did you choose X over Y?"
Positive:
-
"Nice solution! This is much cleaner than..."
-
"Great test coverage on the edge cases"
-
"I learned something new from this approach"
- Distinguish Preferences from Problems
Problems (objective):
-
Bugs and logic errors
-
Security vulnerabilities
-
Performance issues
-
Breaking changes
Preferences (subjective):
-
Code style choices
-
Naming preferences
-
Organization approaches
-
Minor optimizations
Rule: Block on problems, discuss preferences.
Communication Guidelines
Be Constructive
Instead of:
-
"This is wrong"
-
"Why would you do it this way?"
-
"This code is terrible"
Say:
-
"This could cause X issue because..."
-
"Have you considered Y approach? It might..."
-
"This could be improved by..."
Explain Your Reasoning
Weak comment:
This should be refactored.
Strong comment:
Consider extracting this logic into a separate method. It's used in three places and would be easier to test and maintain as a standalone function.
Ask Questions
Use questions to understand and guide:
-
"What happens if X is null here?"
-
"Could this be simplified using Y?"
-
"Have you considered the case where...?"
Acknowledge Good Work
Don't only point out problems:
-
"Clever use of X to solve Y"
-
"Great test coverage"
-
"This is much cleaner than the old approach"
-
"Nice documentation"
Be Humble
You might be wrong:
-
"I might be missing something, but..."
-
"Could you explain why...?"
-
"I'm not familiar with X, but..."
Common Review Patterns
Code Smells to Watch For
Long methods/functions:
-
Hard to understand
-
Difficult to test
-
Multiple responsibilities
Duplicated code:
-
Maintenance burden
-
Inconsistent behavior
-
Missed bug fixes
Complex conditionals:
-
Hard to reason about
-
Error-prone
-
Difficult to test
Large classes:
-
Too many responsibilities
-
Hard to maintain
-
Tight coupling
Magic numbers/strings:
-
Unclear meaning
-
Hard to change
-
Error-prone
Security Red Flags
-
Hardcoded credentials or secrets
-
SQL injection vulnerabilities
-
XSS vulnerabilities
-
Missing input validation
-
Insecure data storage
-
Weak authentication
-
Missing authorization checks
Performance Concerns
-
N+1 query problems
-
Inefficient algorithms (O(n²) when O(n) possible)
-
Memory leaks
-
Unnecessary database calls
-
Large data structures in memory
-
Blocking operations in async code
Review Standards
Establish Team Norms
Define standards for:
-
Code style and formatting
-
Naming conventions
-
Comment requirements
-
Test coverage expectations
-
Documentation needs
Document standards:
-
Style guides
-
Architecture decision records
-
Review checklists
-
Example code
Review Checklist
Use a consistent checklist:
-
Code is correct and handles edge cases
-
Tests exist and pass
-
No security vulnerabilities
-
Performance is acceptable
-
Code is readable and maintainable
-
Documentation is updated
-
No breaking changes (or properly communicated)
-
Follows team conventions
Handling Disagreements
When You Disagree
If it's a preference:
-
State your opinion
-
Explain your reasoning
-
Accept the author's choice
-
Move on
If it's a problem:
-
Clearly explain the issue
-
Provide evidence or examples
-
Suggest alternatives
-
Escalate if needed
When Author Disagrees
Listen and understand:
-
They may have context you lack
-
There might be constraints you don't know
-
Your suggestion might not fit
Discuss, don't dictate:
-
Explain your concerns
-
Ask questions
-
Find common ground
-
Compromise when appropriate
Review Timing
Response Time
Aim for:
-
Small PRs: Within 4 hours
-
Medium PRs: Within 1 day
-
Large PRs: Within 2 days
If you can't review promptly:
-
Let the author know
-
Suggest another reviewer
-
Set expectations
Review Size
Optimal PR size:
-
200-400 lines of code
-
Focused on single concern
-
Reviewable in 30-60 minutes
For large PRs:
-
Request breakdown if possible
-
Review in multiple passes
-
Focus on high-level first
-
Consider pair review
Mentoring Through Reviews
Teaching Opportunities
Use reviews to share knowledge:
-
Explain patterns and practices
-
Share relevant resources
-
Demonstrate better approaches
-
Encourage questions
Growing Reviewers
Help others become better reviewers:
-
Invite junior developers to review
-
Explain your review comments
-
Discuss review decisions
-
Share review best practices
Anti-Patterns to Avoid
❌ Nitpicking without value - Focus on meaningful improvements ❌ Blocking on style preferences - Use automated tools instead ❌ Rewriting in your style - Respect different approaches ❌ Reviewing too quickly - Take time to understand ❌ Being overly critical - Balance criticism with praise ❌ Ignoring context - Consider constraints and tradeoffs ❌ Making it personal - Focus on code, not the person
Review Outcomes
Approve
Code meets standards and is ready to merge:
-
All critical issues addressed
-
Tests pass
-
Documentation updated
-
No blocking concerns
Approve with Comments
Minor issues that don't block merge:
-
Style suggestions
-
Future improvements
-
Questions for discussion
-
Nice-to-have changes
Request Changes
Issues that must be addressed:
-
Bugs or logic errors
-
Security vulnerabilities
-
Missing tests
-
Breaking changes
-
Architectural concerns
Reject (Rare)
Fundamental problems requiring redesign:
-
Wrong approach entirely
-
Doesn't solve the problem
-
Creates major technical debt
-
Violates core principles
Quick Reference
Good review comment structure:
-
Identify the issue
-
Explain why it's a problem
-
Suggest a solution
-
Indicate severity (blocking vs suggestion)
Example:
[Blocking] This query will cause N+1 problem when loading related records. Consider using eager loading with includes() to fetch all data in a single query. This will significantly improve performance with large datasets.
Remember:
-
Be kind and constructive
-
Focus on the code, not the person
-
Explain your reasoning
-
Acknowledge good work
-
Know when to compromise
-
Foster learning and growth