My first contribution to a widely used open-source project was a two-line fix to an error message in a Composer-related library. It took three weeks from opening the pull request to the merge, mostly because I did not read the contributing guide and changed things the maintainers did not want changed. Since then I have contributed to Laravel ecosystem packages, a few JavaScript tooling projects and some documentation sites, and maintained packages myself. From both sides, the path that works is the same.
This guide is for developers who use open source every day and want to give back, but do not know where to start.
Step 1: choose a project you already use
The best first project is one whose behaviour you understand from using it: a framework, a library in your
composer.json or package.json, a CLI tool you run daily. You already know what correct behaviour looks
like, and you may already have hit a bug.
Signals of a project that welcomes contributions:
- a
CONTRIBUTING.mdfile and a code of conduct; - issues labelled
good first issueorhelp wanted; - recent maintainer replies on issues and pull requests (days, not months);
- pull requests from people outside the core team getting merged.
Very large projects, such as language runtimes, have rigorous processes and long review cycles. They are great to contribute to, but a smaller library maintained by a few people is often a better first step.
Step 2: pick an issue, and ask before working
Good first issues are small and well defined: a clear bug with steps to reproduce, a documentation gap, a missing test, an error message that could be clearer.
Before writing code, comment on the issue:
I would like to work on this. My plan is to change X in Y and add a test for Z. Does that approach sound right?
This avoids duplicate work, and maintainers often reply with context you would not have found yourself ("we plan to remove Y next release", "please also handle case W"). If nobody answers in a week, it is usually fine to proceed.
Step 3: reproduce first
Fork the repository, clone your fork, and get the project's test suite running locally before changing anything:
git clone https://github.com/your-user/project.git
cd project
git remote add upstream https://github.com/original-org/project.git
composer install # or npm ci, pip install -e ".[dev]", and so on
composer test # whatever the project uses
Then reproduce the bug, ideally as a failing test. A failing test is the strongest possible bug report and makes your fix easy to review.
Step 4: read the rules
CONTRIBUTING.md usually covers:
- Branch to target:
main, or a specific version branch for bug fixes. - Code style: a formatter or linter configuration you must run.
- Commit messages: some projects use Conventional Commits; some want a specific prefix.
- Tests and changelog: whether a test is required and whether you edit the changelog.
- Legal requirements: a Developer Certificate of Origin (DCO) sign-off or a Contributor License Agreement (CLA).
A DCO sign-off is a line in each commit stating you have the right to submit the code:
git commit -s -m "Fix error message when lock file is missing"
# adds: Signed-off-by: Your Name <you@example.com>
A CLA is a one-time agreement signed through a bot on your first pull request. If your employer owns code you write, check your employment contract or ask before signing.
Step 5: make a small, focused change
The single most important rule: one pull request, one purpose. Do not reformat files you did not change, rename variables you happen to dislike, or fix a second unrelated bug in the same pull request. Each extra change makes review harder and the merge less likely.
git switch -c fix/missing-lock-file-message upstream/main
# make the change and the test
composer test
composer lint
git push origin fix/missing-lock-file-message
Step 6: write a pull request description that answers questions
A useful structure:
## What
Show a clear error when composer.lock is missing instead of a PHP warning.
## Why
Fixes #1423. Users running the command in a fresh checkout see "Undefined array key" (see issue for trace).
## How
Check for the file before reading it and throw LockFileNotFound with the expected path.
## Tests
Added LockFileTest::test_missing_lock_file_has_clear_message. Existing suite passes locally.
Link the issue, describe what you tested, and mention anything you were unsure about. Screenshots help for UI or output changes.
Step 7: handle review well
Review comments are about the code, not about you. Maintainers are often volunteers reviewing in their spare time.
- Respond to every comment, even with "done".
- If you disagree, explain your reasoning once, then accept the maintainer's decision; it is their project.
- Push follow-up commits rather than force-pushing during review, unless the project asks you to squash. Follow-up commits make it easy to see what changed.
- If CI fails, fix it before asking for another review.
- Be patient. A week without response is normal; a polite ping after two weeks is fine.
Step 8: after the merge
Update your fork, delete the branch, and look for the next issue. Second contributions are much easier: you know the codebase, the maintainers recognise your name, and the setup already works.
Contributions do not have to be code. Triaging issues (reproducing reports, asking for missing details), improving documentation and answering questions are valuable and often more needed than new features.
Finding time and keeping momentum
Contributions do not need large blocks of time. Many of mine were done in two or three evenings: one to set up and reproduce, one to fix and test, one to respond to review. Some employers allow time for upstream fixes to dependencies the company uses, which is a good argument to make: a fix upstream means one less patch to maintain internally. Track your contributions in a short list; it is satisfying, and useful in performance reviews and job interviews.
Common mistakes
| Mistake | Why it hurts | Do this instead |
|---|---|---|
| Large first pull request | Hard to review, likely to stall | Small, focused change |
| Not reading CONTRIBUTING | Wrong branch, style or missing sign-off | Read it first, follow it exactly |
| No test | Reviewers must verify manually | Add a failing test, then the fix |
| Unrelated formatting changes | Noise in the diff | Change only what the fix needs |
| Arguing every comment | Reviewer fatigue | Explain once, then accept |
Key takeaways
- Start with a project you already use and an issue you understand.
- Ask on the issue before starting, and reproduce the bug as a failing test.
- Follow the contributing guide exactly, including DCO or CLA requirements.
- Keep the pull request small and the description complete.
- Treat review as collaboration, be patient, and come back for a second contribution.
References
- GitHub Docs, Contributing to a project: https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project
- Open Source Guides, How to Contribute to Open Source: https://opensource.guide/how-to-contribute/
- Developer Certificate of Origin: https://developercertificate.org/
- GitHub Docs, Creating a pull request from a fork: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork
Comments
0No comments yet. Be the first to comment!
Sign In to post a comment.