Most engineers think code review is about finding bugs. While that is one benefit, the real value of code review lies elsewhere: knowledge transfer, design consistency, and team growth. After years of reviewing thousands of pull requests, here is what I have learned about doing it well.
The Purpose of Code Review
Code review serves multiple purposes, in order of importance:
- Knowledge sharing -- the reviewer learns about changes they did not write, and the author learns from feedback.
- Design consistency -- ensures the codebase follows agreed-upon patterns.
- Catching issues early -- bugs, edge cases, and performance problems.
- Mentoring -- a place for more experienced engineers to guide less experienced ones.
What to Look For
When reviewing code, I use a layered approach:
Layer 1: Intent and Design
- Does the PR description clearly explain why this change is needed?
- Is the approach sound? Would a different pattern be simpler or more maintainable?
- Does it fit the existing architecture, or does it introduce inconsistency?
Layer 2: Correctness
- Are edge cases handled (null values, empty arrays, concurrent access)?
- Are error paths handled gracefully?
- Are there race conditions or potential deadlocks?
Layer 3: Readability and Maintainability
- Are variable and function names descriptive?
- Is the code self-documenting, or does it need more comments?
- Are there any clever tricks that should be replaced with clearer code?
Layer 4: Performance and Security
- Are there N+1 queries, unnecessary allocations, or missing indexes?
- Is user input validated and sanitized?
- Are secrets or credentials exposed?
How to Give Good Feedback
The way you phrase feedback matters as much as the feedback itself.
Bad: "This is wrong." Good: "This could fail when the array is empty. Consider adding a guard clause:if (!items.length) return []"
Principles for effective feedback:
- Ask questions instead of making demands. "What happens if this is null?" is more effective than "Add a null check here."
- Explain the why. Don't just say what to change -- explain the reasoning.
- Distinguish severity. Use prefixes to make your intent clear:
- Praise good code. When you see a clever solution or clean refactor, say so. Positive reinforcement matters.
Automate the Boring Stuff
A great code review process automates everything that does not require human judgment:
# .github/workflows/pr-check.yml
- name: Lint
run: pnpm lint
- name: Type Check
run: pnpm tsc --noEmit
- name: Test
run: pnpm test
- name: Format Check
run: pnpm prettier --check .
Use tools like:
- ESLint/Prettier for style and formatting.
- TypeScript strict mode for type safety.
- Danger.js for automated PR checks (missing tests, large PRs, changelog updates).
- SonarQube or Codecov for code coverage thresholds.
For the Author: Make Reviews Easy
If you want fast, thorough reviews, make the reviewer's job easy:
- Keep PRs small -- under 400 lines of changes. Large PRs get rubber-stamped.
- Write a clear PR description -- explain the problem, the approach, and any trade-offs.
- Self-review first -- read your own diff before requesting reviews. You will catch obvious issues.
- Respond to every comment -- even if just to say "Done" or explain your reasoning.
Key Takeaways
- Code review is primarily about knowledge sharing and design, not just bug hunting.
- Use layered review -- start with intent/design, then correctness, then readability.
- Phrase feedback as questions and explain the reasoning behind suggestions.
- Automate formatting, linting, and type checking so human reviewers focus on what matters.
- As a PR author, keep your changes small and your descriptions clear.
Crafted by
Abiyyu Abidiffatir Al MajidSoftware Engineer passionate about building scalable web applications and sharing knowledge about modern web development, system design, and emerging technologies.



