15 KiB
Contribution Tips & Best Practices
Project-agnostic tips and insights for successful open source contributions.
General Principles
Start Small
Why:
- Build trust with maintainers
- Learn project workflow
- Understand conventions
- Reduce risk of wasted effort
Good first contributions:
- Documentation improvements
- Typo fixes
- Simple bug fixes
- Test additions
- Small feature additions
Progression:
First PR: Docs/typo fix (learn workflow)
↓
Second PR: Small bug fix (learn codebase)
↓
Third PR: Medium feature (demonstrate ability)
↓
Ongoing: Complex work (trusted contributor)
Communicate Early and Often
Before starting work:
- Comment on issue: "I'd like to work on this"
- Outline your approach: "I plan to..."
- Ask questions: "Should I... or ...?"
- Wait for confirmation: "Sounds good, go ahead!"
During implementation:
- Share progress on complex issues
- Ask when blocked
- Discuss tradeoffs
- Seek early feedback (draft PRs)
After submission:
- Respond to comments promptly
- Be open to feedback
- Explain your reasoning
- Thank reviewers
Why it matters:
- Avoids duplicate work
- Prevents wrong approach
- Builds relationships
- Shows professionalism
Respect Maintainer Time
Remember:
- Maintainers are often volunteers
- They have limited time
- They manage many issues/PRs
- They have context you don't
How to respect their time:
✅ Do:
- Make PR easy to review (small, focused, clear)
- Provide context in description
- Address review comments promptly
- Self-review before submitting
- Follow project conventions exactly
- Ensure CI passes before requesting review
❌ Don't:
- Submit huge PRs without warning
- Ignore review comments
- Argue about style preferences
- Submit broken PRs
- Ping repeatedly for review
- Take criticism personally
Technical Excellence
Follow Conventions Religiously
Why it matters:
- Consistency is crucial
- Shows respect for project
- Makes code maintainable
- Easier to review
What to match:
- Code style and formatting
- Naming conventions
- File organization
- Comment style
- Test patterns
- Commit message format
How to learn conventions:
- Read CONTRIBUTING.md
- Study existing code
- Run linters/formatters
- Ask if unclear
Rule: When in Rome, do as Romans do - even if you disagree.
Write Clear Commit Messages
Good format:
type(scope): brief description (50 chars max)
Longer explanation of what and why (not how).
Wrap at 72 characters.
- Bullet points ok
- For multiple points
Fixes #123
Types:
- feat: New feature
- fix: Bug fix
- docs: Documentation
- style: Formatting
- refactor: Code restructuring
- test: Tests
- chore: Maintenance
Examples:
✅ Good:
fix(auth): prevent session hijacking via cookie theft
Previously, session cookies didn't have SameSite attribute,
allowing CSRF attacks. Now sets SameSite=Strict for all
session cookies.
Fixes #456
❌ Bad:
fix bug
✅ Good:
feat(api): add pagination to user list endpoint
Implements cursor-based pagination for /api/users endpoint
to handle large user bases efficiently. Defaults to 20 items
per page, configurable via ?limit parameter.
- Add pagination logic
- Update API tests
- Document in API reference
Closes #789
❌ Bad:
added feature
Test Thoroughly
Test types to consider:
Unit tests:
- Test individual functions
- Fast and focused
- Mock dependencies
- Cover edge cases
Integration tests:
- Test component interaction
- More realistic
- Fewer mocks
- Verify integration points
E2E tests (when needed):
- Test full user workflows
- Catch integration issues
- Slower but comprehensive
What to test:
- ✅ Happy path (normal case)
- ✅ Edge cases (empty, null, max, min)
- ✅ Error cases (invalid input, failures)
- ✅ Integration (works with other features)
- ❌ Implementation details
- ❌ Third-party code
Test quality:
// ❌ Bad: Tests implementation details
test('should call handleClick', () => {
expect(handleClick).toHaveBeenCalled()
})
// ✅ Good: Tests behavior
test('should increment counter when clicked', () => {
render(<Counter />)
click(getByRole('button'))
expect(getByText('Count: 1')).toBeInTheDocument()
})
Handle Edge Cases
Common edge cases:
- Empty input:
[],"",null,undefined - Boundary values: 0, 1, max, min, -1
- Special characters: quotes, newlines, unicode
- Large input: Performance with big datasets
- Concurrent access: Race conditions
- Network issues: Timeouts, failures
- Permissions: Unauthorized access
How to find edge cases:
- Think about input constraints
- Consider "what if..." scenarios
- Review similar code for bugs
- Look at issue tracker
- Ask in PR description
Example:
// Feature: Format currency
function formatCurrency(amount) {
// Edge cases to consider:
// - amount is negative
// - amount is 0
// - amount is very large
// - amount has many decimals
// - amount is null/undefined
// - amount is not a number
if (amount == null) return '$0.00'
if (typeof amount !== 'number') {
throw new TypeError('amount must be a number')
}
return `$${amount.toFixed(2)}`
}
Code Review Process
Self-Review First
Before requesting review:
-
Review your own changes:
- Read through entire diff
- Check for debugging code
- Remove commented code
- Verify no secrets committed
- Check for todos
-
Test thoroughly:
- All tests pass
- Linting passes
- Manual testing done
- CI passes
-
Check quality:
- Code is clear
- Comments added where needed
- No obvious bugs
- Follows conventions
-
Verify completeness:
- All requirements met
- Edge cases handled
- Documentation updated
- Tests added
Responding to Feedback
Types of review comments:
1. Bugs/Issues (must fix):
Reviewer: "This will crash if data is null"
✅ Good response:
"Good catch! Fixed in commit abc123. Also added a test
to prevent regression."
2. Style/Conventions (must fix):
Reviewer: "Variables should be camelCase per style guide"
✅ Good response:
"Fixed! Updated all variables to match convention."
❌ Bad response:
"I prefer snake_case because..."
[Don't argue about project conventions]
3. Suggestions (evaluate):
Reviewer: "Could simplify this with Array.reduce()"
✅ Good response:
"Great idea! Changed to use reduce. Much cleaner."
or
"I considered reduce, but opted for explicit loop for
clarity since this is a critical path. Happy to change
if you feel strongly."
4. Questions (answer):
Reviewer: "Why did you choose approach X over Y?"
✅ Good response:
"Chose X because [reason]. Y has issue with [problem].
I can add a comment explaining this."
5. Nitpicks (optional):
Reviewer: "Nit: could extract this to a variable"
✅ Good responses:
"Done!"
or
"Good point, but keeping inline for readability here."
General tips:
- Thank reviewers for feedback
- Don't take criticism personally
- Explain reasoning clearly
- Be open to learning
- Fix quickly and push updates
- Resolve threads when addressed
When Reviewers Disagree
If you disagree with feedback:
-
Understand their perspective: "Could you help me understand your concern?"
-
Explain your reasoning: "I chose X because [reason]. Does that address your concern?"
-
Suggest compromise: "What if we [alternative approach]?"
-
Defer to maintainer: "I see your point. Happy to change it."
Remember:
- They know the project better
- They'll maintain your code
- Consistency matters more than "best" approach
- Battles aren't worth fighting
Dealing with Slow Reviews
If no response after reasonable time:
Week 1:
- Wait patiently
- Ensure CI passes
- Fix any issues
Week 2:
- Polite ping: "Hi! Just checking if you had a chance to review this. No rush!"
Week 3:
- Check if action needed from you
- Ask if changes are needed
Week 4+:
- Consider if project is active
- May need to move on
- Don't take it personally
Don't:
- Ping daily
- Demand attention
- Complain
- Give ultimatums
Project Types & Strategies
Large Projects
Characteristics:
- Many contributors
- Formal processes
- Longer review times
- Higher standards
Strategy:
- Read guidelines carefully
- Start with small issues
- Be patient with reviews
- Follow processes exactly
- Engage with community
Examples:
- Linux kernel
- Kubernetes
- React
- VS Code
Small Projects
Characteristics:
- Few maintainers
- Informal processes
- Direct communication
- May need more convincing
Strategy:
- Be more helpful
- Fix multiple small issues
- Suggest improvements
- Be understanding of limited time
- Build relationship
Examples:
- Most projects on GitHub
- Single-maintainer tools
- Niche libraries
Corporate-Backed Projects
Characteristics:
- Paid maintainers
- Clear roadmap
- Professional processes
- May have legal requirements
Strategy:
- Follow process strictly
- Sign CLA if required
- Align with roadmap
- Professional communication
- Expect formal reviews
Examples:
- Google's projects (Angular, Tensorflow)
- Facebook's projects (React, Jest)
- Microsoft's projects (TypeScript, .NET)
Community-Driven Projects
Characteristics:
- Volunteer-run
- Democratic decisions
- May be slower
- Community matters
Strategy:
- Engage in discussions
- Understand consensus
- Be part of community
- Contribute beyond code
- Be patient
Examples:
- Python
- Rust
- Many CNCF projects
Common Mistakes
Technical Mistakes
❌ Skipping tests
- "Tests are someone else's job"
- Tests are requirements
❌ Not testing locally
- "CI will catch it"
- CI is not your test runner
❌ Scope creep
- "While I'm here, I'll also..."
- Keep PRs focused
❌ Ignoring conventions
- "My way is better"
- Consistency > personal preference
❌ Over-engineering
- "Let me add 5 new abstractions"
- Simplicity wins
❌ Copy-pasting without understanding
- "This code looks similar"
- Understand before copying
Process Mistakes
❌ Not claiming issues
- Start work without commenting
- Someone else might also be working
❌ Going silent
- No response to review comments
- Communicate even if busy
❌ Arguing unnecessarily
- Defend every decision
- Pick battles wisely
❌ Huge first PR
- Submit 2000 line PR as first contribution
- Start small
❌ Not reading docs
- Miss CONTRIBUTING.md guidelines
- Read docs first
Communication Mistakes
❌ Demanding
- "When will you review this?"
- Be patient and polite
❌ Defensive
- "You're wrong because..."
- Stay humble and open
❌ Ghosting
- No response after review comments
- Respond even if busy
❌ Over-committing
- "I'll fix all 20 issues"
- Finish one first
Building Reputation
Become a Trusted Contributor
How to build trust:
-
Consistent quality:
- Well-tested code
- Clear communication
- Follow conventions
- Thoughtful changes
-
Reliable:
- Finish what you start
- Respond promptly
- Follow through on commitments
-
Helpful:
- Answer questions
- Help other contributors
- Improve docs
- Triage issues
-
Long-term:
- Multiple contributions
- Sustained engagement
- Show commitment
Benefits:
- Faster reviews
- More trust in changes
- Input on direction
- Possible maintainer role
- References for jobs
Contributing Beyond Code
Other valuable contributions:
Documentation:
- Improve README
- Add examples
- Fix errors
- Write tutorials
Issue triage:
- Reproduce bugs
- Add missing info
- Label appropriately
- Close duplicates
Code review:
- Review others' PRs
- Provide helpful feedback
- Catch issues
- Share knowledge
Community:
- Answer questions
- Welcome newcomers
- Moderate discussions
- Organize events
All of these build reputation!
Career Benefits
OSS as Portfolio
Contributions show:
- Real coding ability
- Can work on production code
- Understand team dynamics
- Write maintainable code
- Take feedback well
Better than personal projects because:
- Code actually used
- Reviewed by experts
- Part of real system
- Demonstrates collaboration
Learning Opportunities
You learn:
- How real projects are structured
- Best practices and patterns
- Code review process
- Working with others
- New technologies
- How to write maintainable code
Networking
Connections made through OSS:
- Maintainers (often senior engineers)
- Other contributors
- Users of the project
- Potential employers
Job Opportunities
Many developers get jobs through:
- OSS contributions on resume
- Connections made
- Direct recruiting from companies
- Demonstrable skills
Staying Motivated
Set Realistic Goals
Start with:
- 1 small PR per month
- Or: contribute to 1 project regularly
- Or: fix bugs you encounter
Don't:
- Try to contribute to 10 projects at once
- Commit to large features right away
- Burn yourself out
Find Projects You Care About
Best contributions come from:
- Tools you use daily
- Problems you've personally faced
- Technologies you want to learn
- Communities you value
Don't contribute just for resume.
Celebrate Wins
Every PR merged is a win:
- First PR merged? 🎉
- Complex feature shipped? 🎉
- Bug you found fixed? 🎉
- Doc helped someone? 🎉
Track your contributions:
- Keep list of merged PRs
- Note what you learned
- Reflect on growth
Handle Rejection
Not all PRs will be merged:
- Timing might be wrong
- Different vision
- Not aligned with goals
- Technical concerns
How to handle rejection:
- Don't take personally
- Understand reasoning
- Learn from feedback
- Try different project
- Ask how to improve
Rejection is normal and ok!
Resources
Learning More
Guides:
- "How to Contribute to Open Source" (opensource.guide)
- Project-specific CONTRIBUTING.md files
- "First Timers Only" (firsttimersonly.com)
Finding Projects:
- github.com/topics/good-first-issue
- up-for-grabs.net
- Projects you already use
- Ask maintainers for suggestions
Communities:
- Project Discord/Slack channels
- OSS contributor forums
- Local meetups
- Online communities
Getting Help
When stuck:
- Search existing issues/docs
- Ask in project's chat/forum
- Comment on issue
- Reach out to maintainers
- Ask in general OSS communities
Don't suffer in silence!
Final Thoughts
Key Principles
- Start small - Build up to complex work
- Communicate - Early, often, respectfully
- Be patient - Reviews take time
- Stay humble - You're always learning
- Think long-term - Build relationships
- Have fun - Enjoy the process!
Remember
- Every expert was once a beginner
- Every project welcomes good contributions
- Every maintainer appreciates help
- Every bug fixed helps users
- Every contribution matters
Good luck with your open source journey! 🚀