Article
My First Real Open Source Contributions (And What I Learned)
My experience contributing to OpenBakalari, fixing API bugs, writing automated tests, and learning how open source development actually works.
I spent a lot of time looking at GitHub repositories before I actually contributed to one. It's easy to browse projects, read through issues, and think about what you'd change. It's a different experience to open somebody else's code, figure out how it works, and send a pull request that might actually get merged.
Recently, I started contributing to OpenBakalari, a project that works with the Bakaláři school system. I wasn't trying to build a huge feature or rewrite anything. I wanted to find real problems, understand them, and fix them properly. That ended up teaching me more than I expected.
Getting Familiar With Someone Else's Code
The first challenge wasn't writing code. It was understanding code I hadn't written. I cloned the repository, installed the dependencies, and started exploring the API. I used curl to send requests and see how the server behaved when it received different inputs.
One issue I found involved the login endpoint. If a client supplied an invalid or expired refresh token, the request could be left without a proper HTTP response. That's a frustrating kind of bug because the client doesn't get a clear answer about what went wrong. The fix was relatively small: make sure the endpoint returns an appropriate error, including 400 invalid_grant, rather than leaving the request hanging. It wasn't a complicated change, but it made the API more predictable.
The Happy Path Isn't Enough
I also worked on error handling for the timetable API. When you're building an endpoint, it's tempting to focus on the successful case: valid token, existing user, available timetable, response sent. But there are quite a few things that can go wrong before you get there. What if the authorization header is missing? What if a JWT is expired? What if a user exists but doesn't have a timetable? Those cases need predictable responses too.
I worked on making the permanent timetable endpoint return meaningful errors, such as 401 for invalid authentication and 404 when a timetable isn't available. It also needed to keep the response format compatible with the API clients that already expected it. This made me realize that error handling isn't just something you add at the end of development. It's an important part of designing an API, and getting it right makes life easier for everyone using it.
Writing Tests Changed How I Thought About Fixes
After working on a few endpoint fixes, I wanted to do something that would keep being useful after the pull request was merged. I decided to add automated API tests using Node.js's built-in node:test runner. The tests check basic endpoints, HTTP methods, and authentication failures. I also added a GitHub Actions workflow so those tests run automatically when code is pushed or a pull request is opened.
Before that, my process was mostly manual. I'd change some code, start the server, send a request, check the response, and repeat. That approach still has its place, especially when investigating a bug, but it becomes inconvenient when you need to verify the same behavior repeatedly. Automated tests make it much easier to catch regressions, and having them run in CI means the checks aren't limited to my computer.
What I particularly liked about this contribution was that it wasn't just fixing one specific problem. It added something that could help prevent future problems as well. Even a relatively small test suite can make a difference when several people are working on the same codebase.
Getting Something Merged Feels Different
The best part was seeing my pull requests get merged. It wasn't a massive feature announcement or anything dramatic. Somebody reviewed the work, decided it was useful, and accepted it into a project I didn't own. That made the whole process feel much more real than working on something locally and pushing it to my own repository.
I also learned that not every pull request gets merged immediately. Some ideas take more work, and some changes stay open for review. That's normal. Opening a pull request is the start of a conversation, not a guarantee that your code is finished. You need to be prepared to explain your decisions, make adjustments, and sometimes accept that there's a better way to solve a problem.
What I'd Tell Someone Starting Out
I used to think an open-source contribution had to be something impressive. A new feature, a major refactor, or hundreds of lines of code. Now I think a better starting point is finding something you can understand and improve. A request that hangs, an endpoint that returns the wrong status code, or a missing regression test might not look particularly exciting, but those are exactly the details that make software more dependable.
I'm still learning, and I definitely don't have everything figured out. But working on a real repository has already made me more comfortable reading unfamiliar code, checking assumptions, testing edge cases, and explaining why a change is necessary. It also showed me that contributing to open source isn't only about writing code. It's about understanding an existing project, respecting the decisions that have already been made, and finding ways to improve things without unnecessarily complicating them.
If you want to see the actual changes, you can find them in my OpenBakalari pull requests. I'm planning to keep contributing whenever I find something interesting to work on, both to improve my programming skills and to get more experience collaborating on real projects.
If you're thinking about contributing to something yourself, you don't need to wait until you're an expert. Find a small problem you can reproduce, understand why it happens, and try to make it better. That's a pretty good place to start.