If you've never contributed to an open source project before (or have only contributed very little), getting started can be intimidating, uncomfortable and outright scary. I'm pretty new to the contributor world myself, it was only a little over a month ago that I had my very first (positive) open source experience. I'd like to lay out how I started in what was (I think) the easiest way possible.
This may seem like a bizarre first step when the goal is to end up contributing to open source projects, but bear with me. The advice I received in college was to "just look for projects to contribute to", and I believe that advice was wrong (at least for me). I don't think that contributing to open source should be the goal, I think it should be the means by which you achieve other goals. Writing code only with the intention of contributing something is a good way to get discouraged or burn out quickly.
Alright then, if I shouldn't go looking for an open source project to contribute to, how do I end up being a contributor? I think the first step is to stop seeing open source as being fundamentally different from everything else. It's not. Most developers use open source libraries every day in their work. The first step to being confident enough to effectively contribute to those libraries is to realize that they are just software, just like what you're writing.
This is the easy part. The entire point of writing code is to solve problems, it's what we do. Most likely, you're writing custom code because there isn't already a library that solves said problem, but there might be a library that comes close. When you realize that there is some hole in a library you're using (or want to use), you've found your in. Whether it be a flaw you found or a feature you need, this problem that needs solving is a gateway to the open source world.
This is, in my opinion, the hard part. Reaching out to strangers to ask a question about their project may come naturally to some people but it most assuredly does not to me. That's why I'm providing a few sub-suggestions for this part.
You may have already done this when you first started using the library, but it's time to look again, keeping your eyes open for the answers to a few questions. Look at the readme, contributors guide, any public documentation, and existing issues to see if you can find an answer to your question. It might be that the maintainers of this project chose not to implement the feature you want for a reason, or that the bug is actually intended behavior for some reason. Also keep your eyes open for any rules/guidelines for making contributions.
This is important, don't tell the maintainers anything about their project. It's theirs, they know more about it than you do I promise. Whatever your goal is, frame it as a question. "Is there a way to do X?" "When I do Y, I get Z, but I expected to get Q, am I doing something wrong?". You should be coming to them with no expectations or prior assumptions, just a problem that needs solving. That problem is fundamentally yours until they agree that the problem is the project's.
Don't sit around waiting for a response from the maintainers of the project. Odds are if you're writing code for a living, you don't have time to do that. Write a workaround to the bug or a function that gives you the feature you want. Write it in your code, not in a copy of the open source library (you don't want to be in the business of maintaining forks). Keep this code as decoupled as possible from your project though, you may need it later.
Eventually the maintainers may get back to you, or they may not. If they do, hopefully they will answer your question. If they are amicable to the idea of adding the solution to their project, you can offer them the code you wrote in step 5 as a way to help. How you offer this code will depend on the project. Sometimes they'll want you to go through a fork/clone/branch/push/pull request process. Sometimes they might want a Git patch. Maybe they just want to see how you did it inline in the issue so they can implement it into their code base however they see fit.
Post down below this post telling me your success stories. How did you go about contributing to a new project? Did you use any of my suggestions from above (even if you did it before reading this post)? Are there any other bits of advice you'd like to give to developers who have not (yet) contributed to an open source project?
One of the most consolidated misconceptions about programming, since the early days, is the idea that such activity is purely technical, completely exact in nature, like Math and Physics. Computation is exact, but programming is not.