What This Template Is For
Code reviews are one of the most effective quality gates in software development, but they fail when reviewers lack a consistent framework for what to check. Without a checklist, reviews default to style nitpicks and surface-level comments while security vulnerabilities, performance regressions, and missing test coverage slip through.
This template provides a structured checklist that reviewers can work through on every pull request. It covers six dimensions: correctness, security, performance, readability, testing, and operational readiness. The goal is not to slow down reviews but to make them more thorough and consistent. A reviewer who works through this checklist in 15-20 minutes will catch significantly more issues than one who skims code for 5 minutes.
Use this template with your Definition of Done Template to align on what "review complete" means across the team. For the broader engineering process, the Technical PM Handbook covers how product managers can support engineering quality without micromanaging code decisions. The Feature Flag Template is also relevant when reviewing code that includes flag-gated rollouts.
When to Use This Template
- You are establishing a code review process for a new team
- Review quality is inconsistent and you want a shared standard
- A post-incident review identified a missed issue that a review should have caught
- You are onboarding junior engineers who need guidance on what to look for in reviews
- Your team is adopting new security or performance requirements that should be checked in every review
- You want to reduce back-and-forth by giving authors a self-review checklist before requesting review
How to Use This Template
- Share the checklist with your team and agree on which sections are mandatory versus situational. Not every PR touches all six dimensions.
- Authors should self-review against the checklist before requesting a review. This catches the obvious issues and saves reviewer time.
- Reviewers work through the relevant sections for each PR. Check the items that pass. Add comments on items that need attention.
- Use the severity labels (Blocker, Major, Minor, Nit) to prioritize feedback. Blockers must be fixed before merge. Nits are optional improvements.
- Revisit the checklist quarterly. Add items based on recurring issues. Remove items that are no longer relevant or are automated by linters.
The Template
PR Summary Review
- ☐ PR title clearly describes the change
- ☐ PR description explains the what and why (not just the how)
- ☐ Link to the ticket or issue is included
- ☐ Screenshots or recordings included for UI changes
- ☐ Breaking changes are flagged in the description
- ☐ Migration steps documented if applicable
Correctness
- ☐ Code does what the ticket or spec requires
- ☐ Edge cases are handled (null inputs, empty arrays, boundary values)
- ☐ Error handling covers expected failure modes
- ☐ Error messages are actionable (not generic "something went wrong")
- ☐ Data validation exists at API boundaries
- ☐ Race conditions are addressed in concurrent code
- ☐ Database queries use correct indexes and avoid N+1 patterns
- ☐ API contract matches the specification (field names, types, status codes)
Security
- ☐ User input is sanitized before use in queries or templates
- ☐ SQL injection, XSS, and CSRF protections are in place
- ☐ Authentication checks are present on all protected endpoints
- ☐ Authorization checks verify the user has permission for the specific resource
- ☐ Secrets and credentials are not hardcoded (use environment variables)
- ☐ Sensitive data is not logged (passwords, tokens, PII)
- ☐ Dependencies do not have known critical vulnerabilities
- ☐ File uploads are validated for type and size
Performance
- ☐ Database queries are efficient (checked with EXPLAIN if complex)
- ☐ No unnecessary database calls inside loops
- ☐ Large datasets are paginated, not loaded into memory
- ☐ API responses include only necessary fields
- ☐ Caching is used where appropriate (and cache invalidation is handled)
- ☐ Async operations are non-blocking where possible
- ☐ Bundle size impact is acceptable for frontend changes
Readability
- ☐ Variable and function names are descriptive
- ☐ Functions have a single responsibility
- ☐ Complex logic has inline comments explaining why (not what)
- ☐ Magic numbers are replaced with named constants
- ☐ Code follows the project's style guide and conventions
- ☐ No dead code, commented-out blocks, or TODO items without tickets
- ☐ File and module organization follows project patterns
Testing
- ☐ New code has unit tests
- ☐ Tests cover happy path and error cases
- ☐ Tests are deterministic (no flaky dependencies on time, network, or order)
- ☐ Integration tests cover new API endpoints or data flows
- ☐ Test descriptions clearly state what is being tested
- ☐ Mocks and stubs are minimal and well-justified
- ☐ Coverage meets the team threshold (check CI report)
Operational Readiness
- ☐ Logging is sufficient to debug issues in production
- ☐ Metrics or events are emitted for key operations
- ☐ Feature flags are used for risky changes
- ☐ Database migrations are backward-compatible
- ☐ Configuration changes are documented
- ☐ Rollback plan exists for the change
- ☐ Monitoring alerts are updated if thresholds change
Severity Labels
| Label | Meaning | Action Required |
|---|---|---|
| Blocker | Prevents merge. Correctness, security, or data integrity issue. | Must fix before approval |
| Major | Significant improvement needed. Performance or reliability concern. | Should fix before merge |
| Minor | Improvement suggested. Readability or maintainability concern. | Fix recommended, merge OK |
| Nit | Style preference or optional improvement. | Author's discretion |
Filled Example: User Authentication Endpoint Review
PR Summary Review
- ☑ PR title clearly describes the change: "Add OAuth 2.0 login endpoint with Google provider"
- ☑ PR description explains the what and why
- ☑ Link to ticket: PLAT-1234
- ☐ Screenshots: Missing. Add screenshot of the OAuth consent screen flow.
- ☑ Breaking changes: None flagged
- ☑ Migration steps: New
oauth_tokenstable migration included
Correctness
- ☑ Code implements Google OAuth 2.0 code exchange flow per the spec
- ☑ Edge cases: handles expired auth codes, invalid state parameter, revoked tokens
- ☐ Blocker. The
/auth/callbackendpoint does not validate thestateparameter against the session. This allows CSRF attacks on the login flow. Compare thestatequery param againstreq.session.oauthStatebefore exchanging the code. - ☑ Error messages return appropriate HTTP status codes (401 for invalid code, 400 for missing params)
- ☑ API contract matches the spec
Security
- ☑ User input sanitized (state, code params are validated before use)
- ☐ Blocker. The Google client secret is hardcoded on line 42. Move to
process.env.GOOGLE_CLIENT_SECRET. - ☑ Authentication: new endpoint is correctly public (no auth required for login)
- ☑ Authorization: token endpoint correctly scopes to the requesting user
- ☑ Sensitive data: access tokens are not logged
- ☑ Dependencies:
google-auth-libraryis on latest stable
Performance
- ☑ Token exchange is async and non-blocking
- ☑ User lookup uses indexed email column
- ☐ Minor. The
findOrCreateUserfunction makes two database queries (SELECT then INSERT). Consider usingINSERT ... ON CONFLICT DO UPDATEto reduce to one round trip.
Testing
- ☑ Unit tests cover code exchange, token storage, error cases
- ☑ Integration test covers full OAuth flow with mocked Google responses
- ☐ Major. No test for expired token refresh. Add a test case where the access token is expired and verify the refresh token flow works correctly.
- ☑ Tests are deterministic (time-based token expiry uses a fixed clock in tests)
Reviewer Decision
Status: Request Changes (2 blockers, 1 major)
Key Takeaways
- Self-review by the author before requesting a review eliminates 30-40% of common issues. Make it a team norm.
- Use severity labels to separate blocking issues from style preferences. This prevents reviews from becoming bike-shedding sessions.
- Security and correctness checks should be non-negotiable on every review. Performance and readability checks can be adjusted based on PR scope.
- Keep the checklist in your repository as a
REVIEW.mdor PR template. This makes it part of the workflow rather than a separate document people forget. - Review the checklist quarterly. If the same issue keeps appearing, consider automating it with a linter rule or CI check instead.
- Time-box reviews to 30 minutes for standard PRs. If a PR takes longer than 30 minutes to review, it is too large. Ask the author to split it.
