Tutorial 1: Write a Reviewable PR
- Contributor
- 3 days ago
- 3 min read
The hardest part of code review is the author's job, not the reviewer's. A reviewable PR gets reviewed fast and well.
Step 1: Small (10 min)
The strongest signal of PR quality is size.
| Lines changed | Outcome | |---------------|---------| | < 100 | Thorough review | | 100-400 | Decent review | | 400-800 | Skim | | 800+ | LGTM with a sigh |
Aim for < 300 lines. Bigger = split it.
Generated files don't count. Logic changes do.
Step 2: One Concern Per PR (10 min)
Don't:
Mix refactor with feature
Add a new endpoint and fix an unrelated bug
Bundle dependency updates with logic changes
Each is a separate PR.
Mixed PRs are hard to review. Reviewer can't focus; reviewer can't bisect later.
Step 3: Write a Clear Title (5 min)
✓ "Add idempotency keys to /payments endpoint"
✗ "fix"
✗ "WIP"
✗ "Changes from yesterday"
Title should answer "what changed?" in 5 seconds.
For repos with commit conventions: feat(payments): add idempotency keys.
Step 4: Write a Useful Description (15 min)
Template:
## Why
[The problem this solves; the motivation]
## What
[What the change does; key decisions]
## How to test
[Specific steps the reviewer can run]
## Screenshots / videos
[For UI changes]
## Related
[Tickets, RFCs, previous PRs]
Reviewer should understand without asking.
Don't paraphrase the diff. Reviewers can read code. Explain context the diff can't show.
Step 5: Self-Review First (10 min)
Before requesting review, read your own PR top-to-bottom:
Are there debug prints?
Did I commit the right files?
Is the diff readable?
Are there obvious improvements I missed?
Catches half the issues before reviewer sees them.
Step 6: Split by Logical Unit (10 min)
A "feature" might span:
DB migration
Backend logic
API
Frontend
That's 4 PRs, not 1:
1/4: Add user_settings DB migration
2/4: Add settings service backend
3/4: Add /api/settings endpoint
4/4: Add settings UI
Each reviewable in isolation. Each shippable independently.
Step 7: Don't Refactor in the Same PR (10 min)
Tempting:
While I'm in this file, let me clean up these adjacent functions...
Result: a 50-line feature change in a 500-line diff.
Split:
Refactor PR (with no behavior change)
Feature PR (small, focused)
Reviewers can verify the refactor is safe; then focus on the feature.
Step 8: Mark Drafts as Draft (5 min)
GitHub / GitLab support draft PRs.
For work-in-progress: open as draft. Reviewers know not to spend time yet.
When ready: convert to "ready for review."
Step 9: Respond Promptly to Feedback (10 min)
After the review:
Acknowledge each comment ("Fixed", "Disagree because...", "Done in commit X")
Address all or explain why not
Re-request review after pushes
Slow responses = reviewer loses context. Fast iteration = fast merge.
Step 10: Keep PRs Open Briefly (5 min)
A 2-week-old PR has:
Conflicts
Cold context (reviewer forgot the problem)
Possibly outdated requirements
Aim for 24-48h from open to merge for small PRs.
If it's stuck longer: re-evaluate (smaller scope? different approach?).
What You Just Did
Reviewable PRs: small, focused, well-titled, well-described, self-reviewed, logically split, no mixed refactors, draft state, prompt responses, short lifecycles. Author-side discipline.
Common Failure Modes
Mega PR. Reviewer rubber-stamps; bugs slip.
No description. Reviewer guesses at intent.
Mixed refactor + feature. Can't tell what changed.
Refusing feedback. Reviewer disengages; quality drops.
WIP code marked ready. Wastes reviewer time.


