The Perfect Pull Request: A Template for Open Source Contributors That Gets Merged in Under 24 Hours
You’ve written the code. Tests pass. You’re proud of it. You open a pull request on a popular open source project, write a one-liner description, and hit submit.
Three weeks later, it’s still sitting there. No comments. No merge. Nothing.
Build a Custom AI-Powered PR Reviewer with Claude API and GitHub Webhooks — Here’s the Exact Code
Build a Custom AI-Powered PR Reviewer with Claude API and GitHub Webhooks — Here’s the Exact Code You’ve… ...
Sound familiar? It’s not your code that’s the problem. It’s your pull request description.
I’ve maintained open source projects for years, and I’ve reviewed thousands of PRs. The ones that get merged quickly share one thing: a clear, structured description that makes the maintainer’s job trivial.
Why Hire Vietnamese Developers in 2025? A CTO’s Playbook for Cost-Effective Offshore Teams
TL;DR: Hiring Vietnamese developers gives you high-quality engineering talent at 40–60% lower cost than US/EU rates, with strong… ...
Here’s the exact template we use at ECOA AI — and how it cut our average PR merge time from 4 days to under 24 hours.
Why Most PRs Get Ignored
Let’s be honest. Open source maintainers are drowning. They have day jobs, families, and 47 other unread notifications. When they open your PR, they’re asking three questions:
- What does this change? (And why should I care?)
- Is it safe to merge? (Did you break anything?)
- How do I test this? (Can I verify it works?)
If you don’t answer those in the first 10 seconds, your PR gets marked “read later” — and “later” never comes.
A study of 5,000 merged PRs on GitHub showed that PRs with descriptions longer than 250 words had a 34% higher merge rate than those with one-liners. But length alone isn’t enough. You need structure.
The Template That Works
Here’s the exact markdown template we use. Copy it, adapt it, and watch your merge rate climb.
markdown
## Description
[2-3 sentences explaining what this PR does and why it's needed. Include the problem and the solution.]
Closes #[issue_number]
## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would break existing functionality)
- [ ] Documentation update
## How Has This Been Tested?
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing (describe steps below)
**Test steps:**
1. Run `npm test`
2. Call endpoint `/api/v1/users` with payload `{ "email": "test@example.com" }`
3. Verify response status 200 and user created
## Screenshots (if applicable)
[Include before/after screenshots for UI changes, or terminal output for CLI tools]
## Checklist
- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
That’s it. Simple, but effective.
Breaking Down Each Section
Description
Don’t write “Fixed bug.” Write:
“The user registration endpoint was returning a 500 error when the email field contained uppercase characters. This PR normalizes emails to lowercase before validation, matching the database constraint.”
See the difference? The second one tells the maintainer *what* changed, *why* it happened, and *how* it’s fixed. It also references the issue number — critical for traceability.
Type of Change
This saves the maintainer from guessing. Is it safe to cherry-pick into a release branch? If it’s a breaking change, they need to know immediately.
How Has This Been Tested?
Be specific. “I ran the tests” is useless. “I added 3 new unit tests covering edge cases A, B, and C, and verified that all existing 47 tests still pass” is gold.
If you did manual testing, include exact steps. A maintainer in Vietnam (like our team in Ho Chi Minh City) might be reviewing your PR at 10 PM local time. They don’t have time to figure out how to reproduce your test scenario.
Screenshots
For UI changes, a screenshot is worth a thousand words. For API changes, show a curl command and the response. For performance improvements, show a benchmark comparison.
We once had a PR that reduced API latency by 40%. The maintainer merged it in 2 hours because the description included a side-by-side benchmark graph.
Checklist
This isn’t just for show. It forces you to do a self-review. Did you actually run the tests? Did you update the docs? Did you check for warnings?
Honestly, the number of times I’ve seen a PR with “I have performed a self-review” unchecked — and the code clearly wasn’t reviewed — is staggering. Don’t lie. Maintainers can tell.
Real-World Results
We use this template across all our open source projects at ECOA AI. Our team of Vietnamese developers — based in Can Tho and Ho Chi Minh City — adopted it last year.
Before the template, our average time from PR submission to merge was 4.2 days. After, it dropped to 0.8 days. That’s a 5x improvement.
More importantly, our PR rejection rate fell from 22% to 6%. The main reason? Maintainers could immediately understand the change and verify it was safe.
When to Break the Rules
This template isn’t one-size-fits-all. For tiny PRs (like fixing a typo), a one-line description is fine. For huge PRs (500+ lines), consider splitting them into smaller chunks first.
But for 90% of your PRs, this template works. Use it.
A Note on Open Source Etiquette
A great PR description is just the start. You also need to:
- Respond to feedback quickly. If a maintainer asks for changes, make them within 24 hours. Momentum matters.
- Rebase frequently. Don’t let your PR fall behind the main branch. A PR that’s easy to merge gets merged.
- Be polite. Remember that maintainers are volunteers. A little gratitude goes a long way.
One of our Vietnamese developers once spent a weekend fixing a bug in a popular JavaScript library. He used this template, responded to every comment within an hour, and the PR was merged in 6 hours. The maintainer later thanked him for making the review process so smooth.
Frequently Asked Questions
Should I include the PR template in my own open source project’s CONTRIBUTING.md?
Absolutely. Put the template in a file called `.github/PULL_REQUEST_TEMPLATE.md` in your repository. GitHub will automatically pre-fill it when contributors open a PR. It sets expectations and reduces back-and-forth.
What if the project already has a PR template? Should I overwrite it?
No. Respect the project’s existing template. If it’s missing key sections, add them as comments or additional headers. The goal is to make the maintainer’s life easier, not to impose your own style.
How do I handle PRs that are too large for this template?
Break them into smaller, logical chunks. Each PR should do one thing. If you can’t describe the change in 2-3 sentences, it’s too big. Split the work into multiple PRs that build on each other.
Does this template work for private company repos too?
Yes, even more so. In a corporate setting, code reviews are often asynchronous across time zones. A clear PR description saves your teammates from context switching. We use the same template for our client projects at ECOA AI, and it’s reduced our review cycle by 60%.
Related reading: Why Smart Tech Leaders Hire Vietnamese Developers: The 2025 Reality Check