Land Your First Open Source PR

Find, evaluate, and submit a real pull request to an open source project.

Introduction

30 Second Summary

Open source projects power nearly every app you use daily, from your browser to your messaging tools. Contributing to one is one of the fastest ways to build real-world credibility as a developer.

In this project, you will find a real open source issue, evaluate whether the project is worth your time, and submit a genuine pull request that stands out in a landscape flooded with AI-generated contributions.

What You'll Build

A real, submitted pull request on a genuine open source repository, along with a repeatable system for discovering and evaluating contribution opportunities.

By the end of this project, you'll have:

  • A pull request submitted to a real open source project with active maintainers.
  • A personal project health evaluation checklist you can reuse every time you consider contributing to a new repository.
  • A contribution message template that signals quality to maintainers and separates you from AI-generated noise.
  • Secret Mission: A reusable shell script that automates your GitHub issue discovery with custom filters for language, star count, and recency.

Are there any prerequisites?

You should be comfortable with Git (branching, commits, push/pull) and have an existing GitHub account. You also need familiarity with at least one programming language such as Python, Go, C++, or JavaScript.

Hunt for Issues Using GitHub's Advanced Search

The biggest reason first-time open source contributions fail has nothing to do with writing code. It comes down to picking the wrong issue on the wrong project.

A stale issue on a dead repository wastes hours with nothing to show for it. In this step, you'll use GitHub's advanced search to find real, actionable issues that match your skills and are genuinely waiting for a contributor.

In this step, get ready to:
  • Craft a GitHub search query using advanced qualifiers.
  • Refine your filters and bookmark 3-5 promising issues.
  • Explore curated aggregator sites as backup sources.
Craft your search query

GitHub's global search page lets you combine multiple qualifiers into a single query. Each qualifier narrows results to exactly the kind of issue you want: open, beginner-friendly, in your language, and waiting for someone to claim it.

  • Open your browser and go to github.com/search.
  • Make sure you're signed into your GitHub account.

Here's the full search query you'll use. Each qualifier serves a specific purpose:

  • is:open is:issue restricts results to open issues only (not pull requests).
  • label:"good first issue" targets issues that maintainers have curated for beginners.
  • language:go (or python, cpp, javascript) matches your skills.
  • no:assignee filters out issues already claimed by someone else.
  • stars:>100 ensures the project has real users and active maintenance.
  • created:>2026-04-26 limits to issues created in the last 30 days so you avoid stale leftovers.
  • Paste this full query into the GitHub search bar:
is:open is:issue label:"good first issue" language:[[YOUR_LANGUAGE="go"]] no:assignee stars:>100 created:>2026-04-26
  • Set the search type to Issues using the dropdown next to the search bar.
  • Press Enter to run your search.

What do these qualifiers do together?

Each qualifier stacks as an AND filter. The result is a highly targeted list: only open issues, labeled for beginners, in your programming language, on popular projects, posted recently, and not yet taken.

The stars:>100 threshold is intentional. Projects with fewer than 100 stars are often unmaintained or have inactive maintainers who won't review your PR.

You should see a list of issues matching your filters. If the list is empty, try changing your language: value or reducing stars:>100 to stars:>50.

Not seeing any results?

Make sure you selected Issues in the search type dropdown. Without this, GitHub defaults to searching repositories and code, which won't match is:issue.

Also check that the date in created:> uses the format YYYY-MM-DD (ISO 8601). A date like 04-26-2026 will silently fail.

help me fix my GitHub issue search query

Refine and bookmark your results

Your first search gives you a starting point. Now you'll experiment with different filters to cast a wider net and find the best candidates.

  • Try multiple languages to broaden your options. Run the same query with language:python, language:javascript, or any other language you're comfortable with.
  • Swap the label to label:"help wanted" for slightly harder but less contested issues.
  • Add comments:0..3 to find issues that haven't attracted a crowd yet.
  • Bookmark 3-5 promising issues in your browser. You'll evaluate them in the next step.

What makes an issue promising?

Look for issues with clear descriptions, reproduction steps, or acceptance criteria. Skip issues with 5+ comments where people are already debating the approach.

Use curated aggregators as a backup

If GitHub search isn't surfacing good results for your language, curated aggregator sites maintain filtered lists of beginner-friendly issues across thousands of projects.

  • Visit goodfirstissue.dev for curated issues from projects with 10+ contributors and active maintenance.
  • Visit up-for-grabs.net for a filterable list of projects with tasks specifically curated for new contributors.
  • Try appending /contribute to any GitHub repository URL (e.g., github.com/nodejs/node/contribute) to see that project's beginner-friendly issues directly.

Why learn the GitHub search syntax first?

Aggregators are convenient but they lag behind. GitHub's native search gives you real-time results and the query syntax works everywhere on GitHub, from any repo's issue tab to the global search.

Once you know the qualifiers, you can customize searches far beyond what any aggregator offers.

You now have a shortlist of real issues waiting for a contributor. Next up, you'll evaluate which of these projects are actually worth your time before investing hours into a fix.

Evaluate Project Health

You've got a shortlist of 3-5 promising issues. Now the real question: are these projects actually worth your time?

Not every project with "good first issue" labels is healthy. Some have unresponsive maintainers, stale PRs, or hostile review cultures. In this step, you'll evaluate your candidates against concrete health signals so you invest effort where it's most likely to pay off.

In this step, get ready to:
  • Run a 5-signal health check on each candidate project.
  • Review each project's AI contribution policy.
  • Select one issue from a healthy, active project.
Run the 5-signal health check

Most failed first contributions happen because the learner picked a dead or unresponsive project. The code was fine. The project wasn't. This health check prevents that.

For each candidate issue you bookmarked, open the repository and check it against these five signals.

Signal 1: Last merged PR
  • Click the Pull requests tab at the top of the repository page.
  • Click Closed to see recently merged PRs.
  • Look at the dates. A healthy project has PRs merged within the past 2 weeks.

What counts as a red flag?

If the last merged PR was 3+ months ago, the project is likely abandoned or on a long hiatus. Your PR could sit in review limbo for months.

Signal 2: Maintainer response time
  • While still in the Pull requests tab, click into 2-3 recently closed PRs.
  • Check how long it took a maintainer to leave the first review comment.
  • A response within a few days is a green flag. PRs sitting open for weeks with no comment is a red flag.
Signal 3: CONTRIBUTING.md exists
  • Return to the repository's main page (click the Code tab).
  • Look for a CONTRIBUTING.md file in the root directory or a docs/ folder.
  • Open it and confirm it has clear setup instructions and a PR submission process.

Why does CONTRIBUTING.md matter?

A project with a detailed contributing guide signals that the maintainers expect and welcome outside contributions. If it's missing or outdated, you'll be guessing at conventions and risking rejection for style issues.

Signal 4: CI pipeline
  • Go back to the Pull requests tab and open a recently merged PR.
  • Scroll down to see if automated checks ran (green checkmarks or red X icons near commits).
  • A project with a working CI pipeline means tests run automatically on your PR. No CI, or CI that's always failing, means you'll have no way to verify your change didn't break something.
Signal 5: Recent beginner PR merges
  • In the Pull requests tab, search for PRs linked to issues with the good first issue label.
  • Check if other beginners have gotten PRs merged recently.
  • If all beginner PRs are closed without merge, the project may not actually be welcoming to new contributors despite the label.

Speed up the check

You don't need to exhaustively check every signal for every candidate. Start with Signal 1 (last merged PR). If the project fails that one, skip it immediately. Only invest time in the remaining signals for projects that pass the first.

Check the AI policy

This is critical in 2026. AI-generated PRs went from roughly 4 million per month in September 2025 to roughly 17 million per month by March 2026. Maintainers are exhausted and many projects now enforce explicit AI policies.

For each project that passed the 5-signal check, look for its AI contribution policy.

  • On the repository's main page, look for an AI_POLICY.md, agents.md, or a dedicated AI section inside CONTRIBUTING.md.
  • Check 2-3 recently closed PRs for signs of AI-related rejections (comments mentioning "AI generated", "bot", or automated closure).
  • Note whether the project requires AI disclosure, bans AI entirely, or allows it with conditions.

What do real AI policies look like?

Ghostty requires a "vouch" from a maintainer before you can contribute at all. AI-generated contributions are only allowed for accepted issues and maintainers. Drive-by PRs with AI content are immediately closed.

matplotlib bans external AI tooling (bots, agents) from interacting with the project. Using AI to gain understanding of existing code or get solution ideas is acceptable. Solving topics you couldn't solve yourself without AI is not.

If a project explicitly bans AI-generated contributions, you must comply fully. Violating an AI policy will get you permanently banned from the project.

What AI usage IS acceptable for most projects?

Using AI to help you understand existing code you're reading is widely accepted. Getting solution ideas and approaches is fine too. The line is clear: you must be able to explain every line of your PR if a maintainer asks.

Make your decision

You've checked the signals. Now pick ONE issue from your shortlist that passes all health checks. This is the issue you'll actually contribute to.

  • Review your shortlist and eliminate any projects that failed a health signal or have an AI policy you can't comply with.
  • From the remaining candidates, pick the issue that has a clear description with reproduction steps or acceptance criteria.
  • Confirm the issue has 0-2 comments. More than that means other people are already crowding in.
  • Confirm the issue does NOT require deep domain knowledge of the entire codebase.

What makes an ideal first issue?

The best first issue sits in a project where you can see other PRs getting merged within days. It has a description specific enough that you know exactly what "done" looks like. It's scoped tightly enough that you won't need to understand the entire codebase to fix it.

None of your candidates passed?

Go back to Step 1 and run a new search. Try different languages or broaden your star range. You can also try label:"help wanted" instead of label:"good first issue" for slightly harder but less contested issues.

Help me find a healthy open source project to contribute to

You've now selected a real, healthy project with an issue worth solving. Next up, you'll claim that issue and set up your development environment to actually build the fix.

Claim the Issue and Understand the Codebase

You've evaluated your candidate projects and picked an issue on a healthy, active repository. Now it's time to stake your claim and get your hands into the code.

In this step, you'll post a professional comment that tells the maintainer you're serious. Then you'll fork the repo, set up your local development environment, and trace through the relevant code so you understand what you're changing before you change it.

In this step, get ready to:
  • Claim your chosen issue with a professional comment.
  • Fork, clone, and set up the project's dev environment locally.
  • Trace the relevant source files and understand the code patterns used.
Claim the issue properly

Maintainers see dozens of low-effort "I want to work on this" comments every week. A well-crafted claim comment signals that you're a thoughtful human contributor, not an AI bot drive-by.

  • Navigate to your chosen issue on GitHub.
  • Scroll to the comment box at the bottom of the issue.
  • Post a comment using this template, customizing the bracketed sections:
Hi, I'd like to work on this. I've read the contributing guide and I'm
familiar with [[LANGUAGE_OR_TOOL="the language or tool relevant to this issue, e.g. Go"]]. I'll aim to have a PR up within
[[TIMEFRAME="a realistic timeframe, e.g. a few days"]]. Let me know if there's any
additional context I should be aware of.

Why does this comment work?

  • It shows you read the contributing guide. Most people skip it entirely.
  • It commits to a timeframe. Maintainers dislike claimed-but-abandoned issues that block other contributors.
  • It asks for context. This signals you want to do the work correctly.
  • It reads like a human wrote it. In a world of AI-generated spam, that alone makes you stand out.
  • Click the green Comment button to post.

You should see your comment appear immediately beneath the issue description.

Don't see a comment box?

Some repositories restrict commenting to users who have verified their email address or who meet a minimum account age. Check your GitHub notification banner for any verification prompts.

Why can't I post a comment on this GitHub issue?

Fork, clone, and set up the dev environment

A fork is your personal copy of the repository on GitHub. You'll make changes on your fork and later submit a pull request back to the original project.

  • On the repository's main page in GitHub, click the Fork button in the top-right corner.
  • Leave all the defaults and click Create fork.
  • Wait for GitHub to finish creating your fork. You'll be redirected to your copy of the repository.

Now bring the code down to your machine and connect it to the original project.

  • Open your terminal by pressing Ctrl+Alt+T.
  • Clone your fork and set up the upstream remote by running these commands:
git clone https://github.com/[[YOUR_USERNAME="your GitHub username"]]/[[REPO_NAME="the repository name"]].git
cd [[REPO_NAME="the repository name"]]
git remote add upstream https://github.com/[[ORIGINAL_ORG="the original org or username"]]/[[REPO_NAME="the repository name"]].git

What do these commands do?

  • git clone downloads your fork to a local folder.
  • cd moves you into the newly created project folder.
  • git remote add upstream creates a named connection to the original repository. This lets you pull in future changes from the maintainers so your fork stays current.
  • Confirm both remotes are configured by running:
git remote -v

You should see four lines. Two lines for origin (pointing to your fork) and two for upstream (pointing to the original repository).

Only seeing origin?

Double-check that the git remote add upstream command used the correct URL of the original repository, not your fork. Your fork URL contains your username. The upstream URL contains the original organization's name.

Help me fix my remote configuration.

  • Open the project's README.md or CONTRIBUTING.md file and follow their setup instructions to install dependencies and configure the development environment.
  • Run the project's full test suite before making any changes. The specific command varies by project (for example, make test, npm test, pytest, or go test ./...). Check the contributing guide for the exact command.

All tests should pass. This confirms your environment is healthy and gives you a clean baseline before you start editing.

Tests failing before you changed anything?

This is more common than you'd expect. Check the project's open issues for known test failures. If the failures are unrelated to your issue, note them and move on. If you can't get the suite running at all, revisit your setup steps or ask in the project's discussion forum.

Help me troubleshoot failing tests on a freshly cloned project.

Trace the relevant code

Before writing a single line of code, you need to understand how the project solves the problem today. Diving in without reading the surrounding code is the fastest way to get your PR rejected for style mismatches or accidental regressions.

  • Search the codebase for keywords, error messages, or function names mentioned in the issue. Use your editor's global search or grep in the terminal.
  • Read the surrounding code in the file(s) you find. Pay attention to naming conventions, error handling patterns, and how similar functionality is structured.
  • Look at 2-3 recently merged PRs that solved similar issues. These show you what style and approach the maintainers actually accept.

Where AI is acceptable to use

Using AI to help you understand code you're reading is widely accepted, even by projects with strict AI policies. You're building comprehension, not generating a contribution.

Paste a confusing function into your AI tool and ask it to explain the logic. This is the "gaining understanding of existing code" use case that projects like matplotlib explicitly allow.

  • Once you've identified the relevant files, note down which functions or modules need to change and why.

Read the tests too

Find the test file for the module you're changing. It shows you what behavior the project already expects, what edge cases are covered, and how to write your own test when you submit the fix.

You now have a claimed issue, a working local environment, and a solid understanding of the code you're about to change. Next up, you'll write the fix, craft a PR description that proves you're not a bot, and ship it.

Implement, Test, and Ship Your PR

You've identified the relevant code, studied the patterns, and understand what the fix needs to look like. Now it's time to write the actual code and get it in front of the maintainer.

The implementation itself is often the easiest part. What separates merged PRs from ignored ones is how you present your work. Your PR description is where you prove you're a thoughtful contributor in a sea of AI-generated noise.

In this step, get ready to:
  • Create a feature branch, implement the minimal fix, and confirm tests pass.
  • Push your branch and open a pull request with a clear description.
  • Understand how to respond to maintainer feedback like a professional.
Write your fix

Every contribution starts on its own branch. This keeps your work isolated and makes it easy for the maintainer to review a single focused change.

  • Create a feature branch by running this command in your cloned repository:
git checkout -b [[BRANCH_NAME="fix/issue-NUMBER-short-description"]]

Why this branch naming pattern?

The fix/ prefix signals the type of change. The issue number links it to the discussion. The short description helps the maintainer identify it at a glance.

Replace NUMBER with your actual issue number and short-description with 2-3 words describing the fix (e.g., fix/issue-42-null-check-handler).

Now implement the fix. The goal is the smallest change that solves the issue correctly.

  • Make the minimal change that fixes the issue. Resist the urge to refactor other code you notice along the way.
  • Follow the project's code style exactly. Match the linting rules, naming conventions, and file organization you observed in the surrounding code.
  • Add or update tests if the project has a test suite. Look at existing tests to match the testing style.
  • Run the full test suite locally and confirm everything passes.

Why minimal changes matter

Maintainers review PRs line by line. A focused 10-line fix gets reviewed in minutes. A 200-line PR that also refactors three unrelated functions gets ignored for weeks or closed outright.

If you spot other improvements, note them for a separate PR after this one is merged.

Using AI to understand code is fine

Projects like matplotlib explicitly allow using AI to gain understanding of existing code and get solution ideas. The line is clear: you must be able to explain every line of your fix if asked. If you cannot solve the problem without AI doing it for you, choose a different issue.

Craft a PR that gets merged

Your PR description is where you prove you're not an AI agent. Maintainers now receive roughly 17 million AI-generated PRs per month. Your description must demonstrate genuine understanding of the problem and your solution.

  • Push your feature branch to your fork by running this command:
git push origin [[BRANCH_NAME="fix/issue-NUMBER-short-description"]]

Push rejected or permission denied?

Make sure you're pushing to your fork (the origin remote), not the upstream project. You can verify by running git remote -v and checking that origin points to your GitHub username.

Help me debug why my git push is being rejected.

  • Open your fork on GitHub in your browser.
  • You should see a banner at the top suggesting you open a pull request for your recently pushed branch. Click **Compare & pull request**.
  • Confirm the base repository is the upstream project's default branch (usually main or master) and the compare branch is your feature branch.

Now write your PR description. Use this structure as your template:

## What

[One sentence: what this PR does]

## Why

[Link to the issue. Brief explanation of the root cause]

## How

[2-3 sentences explaining your approach and why you chose it]

## Testing

[How you verified this works: test output, manual reproduction steps]

Fixes #[[ISSUE_NUM="ISSUE_NUMBER"]]

What makes this structure work?

The What section gives the reviewer instant context without reading the diff. The Why section links back to the issue so the reviewer doesn't have to search for it.

The How section proves you made a deliberate choice. The Testing section shows you verified your work. AI-generated PRs almost never include real testing evidence.

The Fixes #ISSUE_NUMBER line automatically closes the issue when your PR is merged.

  • Fill in each section with your own words. Write it yourself. Do not paste AI-generated text here.
  • Click **Create pull request** to submit.

You should now see your PR appear on the upstream repository's pull request list. The project's CI pipeline will start running tests on your code automatically.

CI tests failing on your PR?

If the CI pipeline shows red checks, click on the failing test to read the error log. Common causes include formatting differences (the CI may use a stricter linter than your local setup) or missing test coverage for new code paths.

Fix the issues locally, commit the fix, and push again. Your PR updates automatically.

Help me understand why CI is failing on my pull request.

Respond to reviews like a human

Your PR is submitted, but the process isn't over. Maintainer review is where most first contributions either succeed or fizzle out.

  • Expect 1-5 rounds of review. This is normal and not a sign of rejection. Even experienced contributors go through multiple rounds.
  • When a maintainer requests changes, respond within 24-48 hours. Slow responses signal that you've abandoned the PR.
  • If you disagree with feedback, explain your reasoning respectfully. Do not just comply blindly, but do not fight over it either.
  • Never paste AI-generated responses to review comments. Maintainers can tell instantly and it destroys trust.
  • Thank the reviewer when you're done. They are volunteering their time to help you improve your code.

Why does review take multiple rounds?

Maintainers are not gatekeeping. They are protecting the project's users from bugs and inconsistencies. Each round of feedback helps you learn the project's conventions and produce better code.

Research from the MSR 2026 dataset shows 31% of rejected AI PRs were rejected due to workflow issues, not code quality. Showing that you follow the project's process is just as important as writing correct code.

Turn on GitHub notifications

Enable email or mobile notifications for your PR so you see maintainer comments quickly. A fast, thoughtful response makes you memorable. Most first-time contributors disappear after submitting. The ones who respond promptly get invited back.

Secret mission

Build a Reusable Issue-Finder Script

You've just shipped your first PR. But finding that issue took manual searching through GitHub's interface. What if you could automate the discovery process? Build a shell script that constructs GitHub search queries with your preferred filters and opens results in your browser with a single command.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely for free. No paid cloud resources, no subscriptions, no ongoing costs.

Decide whether to keep your resources as-is, pause to come back later, or delete them entirely.

Resources you used:

  • Forked repository on your GitHub account (free).
  • Open pull request on the upstream project (free).
  • Local clone of the forked repository.
  • find-issues.sh script (local file, Secret Mission).

Keep everything running

No action needed. Choose this if your pull request is still open and waiting for maintainer review.

  • Your fork stays on GitHub and keeps your branch history intact.
  • Your pull request stays open for the maintainer to review on their own timeline.
  • Your local clone and find-issues.sh script remain on your machine for future use.

Pause - I'll come back to this later

Leave your fork and pull request open, but clean up local resources to free disk space. You can re-clone later if needed.

  • Keep your fork and PR on GitHub. The maintainer will review on their own timeline.
  • Remove your local clone by running:
rm -rf ~/REPO-NAME

Replace REPO-NAME with the actual name of the repository folder you cloned.

  • Keep find-issues.sh on your machine so you can run it again when you are ready to find your next contribution.

Delete - I don't want to use this again

Remove all project resources from GitHub and your local machine. Only do this if your PR has already been merged or you want to abandon the contribution entirely.

  • Close your pull request (if it has not been merged yet):
  • Open your PR on GitHub.
  • Scroll to the bottom of the conversation and click Close pull request.
  • Delete your fork on GitHub:
  • Navigate to your forked repository on GitHub.
  • Click Settings.
  • On the General settings page, scroll down to the Danger Zone section.
  • Click Delete this repository.
  • Click I want to delete this repository, then click I have read and understand these effects.
  • Type the repository name to confirm, then click Delete this repository.

What about the upstream project?

Deleting your fork does not affect the upstream repository or any merged commits. Your contribution (if merged) stays in the project permanently.

  • Delete your local clone and the find-issues.sh script by running:
rm -rf ~/REPO-NAME
rm ~/find-issues.sh

Replace REPO-NAME with the actual name of the repository folder you cloned. Adjust the path to find-issues.sh if you saved it in a different location.

Nice Work!

Nice Work!

You just did what most developers talk about but never actually do. You contributed to a real open source project.

You've learned how to:

  • Find real issues using GitHub's advanced search filters and evaluate project health to avoid wasting time on dead or hostile repos.
  • Claim an issue with a professional message that signals quality to maintainers in a landscape flooded with AI-generated contributions.
  • Submit a pull request that follows a project's conventions, includes a structured description, and stands out from low-effort submissions.
  • Built a reusable shell script that automates your issue discovery process so you can repeat this workflow weekly.

Ready to quiz yourself?