What Open Source Taught Me That Tutorials Couldn't
Tutorials teach you to write code that works. Open source teaches you to enter code you didn't write, defend changes you believe in, and accept that your solution isn't the only one.
- Open Source
- GitHub
- Software Engineering
- Code Review

Tutorials taught me to write code that works. Open source taught me everything after that. The first pull request I ever opened was against a tool I used daily — a media archiving project called CCExtractor — and I remember the feeling of opening a repository where a thousand people had been working for a decade, where every function had a history and every file had opinions. Nothing in the tutorial curriculum prepares you for that feeling. This essay is about what happens after it.
Understanding before changing
The first lesson is the hardest: you cannot improve a codebase you do not understand, and understanding is not reading. It is mapping. Before my first real patch, I spent hours following call chains, reading the tests to learn the intended behavior, and looking at the recent commits to see what the maintainers cared about. The architecture of an unfamiliar repository is a set of decisions — some deliberate, some accidental, some ten years old. Changing code before you understand the decisions is how you break the thing the maintainers quietly rely on.
Debugging code you didn't write
Every serious bug I have fixed in open source has been in code I did not write. That changes your method. You cannot ask the author, so you interrogate the evidence: the failing test, the stack trace, the git blame, the issue thread where someone described the exact behavior months ago. You learn to bisect, to reproduce in the smallest possible case, to read the changelog like a detective. The skill is not debugging. It is becoming comfortable with being the last person to understand a system, on a deadline, in public.
Why 'my solution works' isn't enough
In a tutorial, the code is graded by whether it runs. In open source, it is graded by whether it belongs. I have had solutions that worked perfectly and were still wrong: wrong because they ignored the project's conventions, wrong because they solved the problem at the wrong layer, wrong because a cleaner pattern already existed that I hadn't read. Maintainers will reject a working patch that is inconsistent with the codebase, and they are right to. The code has to be maintainable by people you will never meet, for years after you are gone.
Code review is the real education
The best code education I have had is review feedback from maintainers. On Zulip and SveltyCMS — projects with exacting standards and generous maintainers — I have had three-line reviews teach me more than any course: why this edge case matters, why this API shape is better, why this fix should live two layers up. The lesson is to take review as information, not judgment. A review is not an attack on your skill; it is a senior engineer sharing the map they spent years drawing.
Backwards compatibility is a form of respect
The biggest conceptual shift was backwards compatibility. In a tutorial, you rewrite freely. In open source, your change will be consumed by code you cannot see, by people who upgrade on their own schedule. A function's signature is a promise. Changing behavior silently is breaking it. I learned to ship deprecation warnings before breaking changes, to keep the old path working alongside the new, and to write migration notes so the change was a transition and not an ambush. Compatibility is not laziness — it is the understanding that software lives in other people's production systems.
Small PRs, tests, and documentation
Open source also taught me the virtues that sound like hygiene and act like leverage. Small pull requests get reviewed and merged; large ones get stale. Tests are not a checkbox — they are the only way a maintainer can trust a patch from a stranger, and the reason a patch lands is often that it arrives with tests already passing. Documentation is the respect you show the next person who has to use what you built — and in open source, the next person might be the maintainer, at 2 a.m., on your feature.
Learning from rejected approaches
Not every pull request lands. Some get closed with a detailed explanation, some with silence. The useful response to rejection is not persistence or retreat — it is reading. The maintainers who took the time to explain why an approach is wrong were giving away the same knowledge they accumulated through years of mistakes. I keep a personal list of rejected designs and what they taught me; it is the most honest documentation of my growth as an engineer, and it is the thing tutorials could never provide.
Contributing across different organizations — a media tool, a chat platform, a CMS — taught me that engineering judgment is portable even when code is not. The questions are the same everywhere: what does this change break, who has to maintain it, what does the history say, what does the test say. Tutorials taught me to write code. Open source taught me to join a conversation that started before I arrived and will continue after I leave — and to make my contribution worthy of that company.
Written by Rajat Yadav. If you enjoyed this, say hello in the guestbook or read another essay.