How to Set Pull Request Size Limits for Open Source Projects
A 19,000 line-of-code pull request landed in Node.js core, and the community erupted. The debate quickly turned to whether LLM-assisted PRs should be banned entirely. But I think the real problem isn’t AI—it’s PR size.
The Real Problem
Large pull requests break code review. A 19K LoC PR is unreviewable by any reasonable standard. Reviewers miss bugs, security issues, and architectural problems because of cognitive overload. The result? Superficial “LGTM” approvals that put critical infrastructure at risk.
The Node.js community discussion made this clear. The top comment with 132 votes stated it plainly:
“Enforce maximum PR sizes with minimal exceptions, enforce test coverage, enforce code style, and enforce security. From there it won’t matter if it’s AI or not.”
Another comment with 27 votes:
“The only real problem here is PR size. 19K LOC is unreviewable by any reasonable standard. The fix is simple: enforce PR size limits and require contributors to demonstrate understanding during review.”
The consensus is clear: size limits solve the governance problem without banning AI assistance.
Recommended Size Limits
Here’s a practical framework I recommend:
| Size Category | Lines Changed | Action |
|---|---|---|
| Small | < 400 lines | Fast-track review |
| Medium | 400-1000 lines | Standard review |
| Large | 1000-2000 lines | Require justification |
| Unacceptable | > 2000 lines | Reject or require split |
Automating Enforcement with GitHub Actions
Let me show you how to enforce these limits automatically. Create a workflow file:
name: PR Size Limiton: pull_requestjobs: check-size: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Check PR size run: | ADDITIONS=$(gh pr view ${{ github.event.pull_request.number }} --json additions --jq '.additions') DELETIONS=$(gh pr view ${{ github.event.pull_request.number }} --json deletions --jq '.deletions') TOTAL=$((ADDITIONS + DELETIONS))
if [ $TOTAL -gt 2000 ]; then echo "PR is too large ($TOTAL lines). Maximum is 2000 lines." exit 1 elif [ $TOTAL -gt 1000 ]; then echo "::warning::Large PR detected ($TOTAL lines). Consider splitting." fi env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}This workflow runs on every pull request and fails if the PR exceeds 2000 lines.
Using Danger.js for Richer Checks
For more sophisticated size checking with generated file exclusion, use Danger.js:
import { danger, warn, fail } from 'danger'
const totalLines = danger.github.pr.additions + danger.github.pr.deletions
if (totalLines > 2000) { fail(`PR is too large (${totalLines} lines). Please split into smaller PRs. Maximum: 2000 lines.`)} else if (totalLines > 1000) { warn(`Large PR (${totalLines} lines). Consider splitting for easier review.`)}
// Exclude generated filesconst generatedFiles = danger.git.created_files.filter(f => f.endsWith('.generated.ts') || f.includes('node_modules'))
if (generatedFiles.length > 0) { console.log(`Excluding ${generatedFiles.length} generated files from size count`)}Adding Size Labels Automatically
You can also automatically label PRs by size:
name: PR Size Labelson: pull_request
jobs: label: runs-on: ubuntu-latest steps: - uses: actions/labeler@v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Add size label uses: actions-ecosystem/action-add-labels@v1 with: labels: | size/${{ steps.size.outputs.category }}Documenting Your Policy
Clear documentation is essential. Add this to your CONTRIBUTING.md:
## Pull Request Size Guidelines
We enforce size limits to ensure thorough code review:
- **Small (< 400 lines)**: Preferred, fast review- **Medium (400-1000 lines)**: Acceptable, standard review- **Large (1000-2000 lines)**: Requires justification in PR description- **Oversized (> 2000 lines)**: Will be rejected; please split
**Tips for splitting large PRs:**1. Separate refactoring from feature changes2. Split by logical component/module3. Create a tracking issue for multi-PR changes4. Stack dependent PRs using GitHub's draft feature
**Exceptions:**Generated code, dependency updates, and vendored files are excluded from line counts.Request an exception by tagging a maintainer with a detailed justification.Common Mistakes to Avoid
I’ve seen projects make these mistakes:
No Written Policy - Document size limits clearly. Unwritten rules create confusion and inconsistency.
Rigid Enforcement Without Exceptions - Allow exceptions with maintainer approval and documentation. Some changes (like vendored library updates) legitimately need to be large.
Counting Only Additions - Consider total lines changed (additions + deletions). A refactor that moves 500 lines should count, even if net additions are small.
Ignoring File Types - Exclude generated files, lockfiles, and vendored code from limits. They inflate counts without adding review complexity.
No Guidance for Splitting - Provide documentation on how to break down changes logically. Contributors want to help, but need direction.
Why This Matters
For critical infrastructure like Node.js or React, security vulnerabilities affect millions of users. Performance regressions have widespread impact. Trust in the ecosystem depends on code quality.
For project sustainability, size limits reduce maintainer burnout and encourage contributor onboarding. Smaller PRs have higher review quality, bugs are caught earlier, and changes are easier to understand and revert.
Summary
In this post, I showed you how to set pull request size limits for open source projects. You learned the recommended size categories, how to automate enforcement with GitHub Actions and Danger.js, and how to document your policy. The key is starting with clear limits, automating enforcement, and providing guidance for contributors.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments