Maintaining an Open Source Package for Six Years Taught Me Contract Law
Six years ago I published a Swift library called BarcodeKit for handling barcode scanning on iOS. It was a weekend project, a few hundred lines, MIT licensed. I expected maybe a dozen stars on GitHub. Instead the package grew to over 4,000 dependents, and I became a maintainer whether I planned to or not. For most of those six years I thought of open source as a technical problem: merge requests, CI pipelines, semantic versioning. Then a contributor sent a cease-and-desist email claiming I had violated the terms of an old BSD-style license embedded in a dependency. That email taught me something no tutorial ever did: a license is a contract.
The Day I Realized a License Was a Contract
It started with a pull request. A new contributor had submitted a patch that included code from a library with a three-clause BSD license. The file headers were intact, so I merged it. Two weeks later I received a formal letter from an attorney representing the original author of that BSD library. The letter demanded I remove the contributed code because the license included a non-endorsement clause I had allegedly violated by using the author's name in my documentation. I had never read the full BSD text; I just assumed "permissive" meant "safe."
That demand forced me to read the license word by word. Section 2 of the BSD 3-Clause says: Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. My README had thanked the contributor by name and listed the library as an inspiration. I had not sought permission. Technically, I was in breach. We settled by removing the name and adding a disclaimer, but the lesson stuck: license terms are legally enforceable promises.
I am not a lawyer. I never took a contracts class. But after that incident I started treating every LICENSE file as a binding document. I read the fine print of MIT, Apache 2.0, GPLv3, and the lesser-used ones like MPL and AGPL. I discovered that most licenses include sections on warranty disclaimer, limitation of liability, and governing law. These are not boilerplate; they allocate risk. And as a maintainer, you are the party accepting that risk on behalf of your project.
The cease-and-desist email itself was informative: it cited specific clauses, referenced the license version, and demanded action within 14 days. I responded within 48 hours, but the anxiety of potentially facing litigation over a hobby project was real. That experience reshaped how I view every pull request. I now check not just the code but the license of every dependency introduced. It adds minutes to each review, but it beats a legal letter.
How Open Source Governance Mirrors Employment Terms
Contributor License Agreements, or CLAs, are the open source equivalent of an employment contract. When a contributor signs a CLA, they grant the project a license to use their contributions, and they often agree to represent that the work is original. As a maintainer, I act like a hiring manager: I review the candidate (the code), check references (the contributor's history), and decide whether to accept. But unlike a manager, I have no HR department, no legal team, and no budget for disputes.
Code review becomes a form of performance evaluation. I assess not just correctness but also license compatibility, potential patent issues, and adherence to project governance. A contributor who submits a patch derived from GPL code into an MIT project is, in effect, violating the terms of both licenses. I have to catch that. The trade-off is that governance work eats into coding time. Some weeks I spend more hours reading license headers and drafting contribution guidelines than writing features.
Burnout from unpaid governance work is common. Studies estimate that roughly 60% of open source maintainers are solo or part-time, and many report stress from legal ambiguity. The autonomy of running your own project is real, but so is the exposure. I have no liability insurance, no corporate shield. If a contributor's code infringes a patent, the lawsuit could name me personally. That risk is rarely discussed in beginners' guides to open source.
The parallel to employment goes deeper: just as an employer can be vicariously liable for an employee's actions, a maintainer can inherit liability from a contributor's mistakes. The legal term is "contributory infringement." If I distribute code that I should have known was infringing, I am liable. That is why large projects like Kubernetes require CLAs and run automated license checks. Small projects cannot afford that infrastructure, but they face the same legal exposure.
Reading License Files: One Key Practice, Not a Checklist
After my legal scare, I adopted a single key practice: reading the full license text of every dependency. I do not rely on summaries or package manager labels. For each new dependency, I open the LICENSE file and scan for three things: warranty disclaimer, governing law, and any non-standard clauses. This takes five minutes per dependency. I also check that the license is compatible with my project's MIT license. For example, if a dependency uses GPL, I cannot include it in BarcodeKit without changing the project license or isolating the code.
This diligence has caught several issues. Once, a dependency's license included a clause that required attribution in advertising materials. My project had no advertising, but if a large company used BarcodeKit in a product, that clause could create obligations. I replaced the dependency with an alternative under MIT. Another time, a dependency's license specified that it was governed by the laws of a country with different copyright standards. I decided the risk was acceptable, but I noted it in my records.
Automated license checking tools exist, but they are not perfect. I use a CI step that runs license-checker and flags any non-MIT-compatible licenses. But the tool only knows about common licenses; it cannot catch custom clauses. Human review is still necessary. I also maintain a spreadsheet of direct and transitive dependencies and their licenses. This is tedious, but it prevents the kind of incident that triggered my first cease-and-desist.
The Three Clauses That Bite Maintainers Most
Three clauses in open source licenses cause the most trouble for maintainers. The first is indemnification. Apache 2.0, for example, includes a section where contributors grant a patent license and agree to indemnify the project for claims arising from their contributions. But many contributors never read that section. If a contributor violates a third-party patent, the project may be protected, but the maintainer's personal liability is not always covered.
The second clause is the warranty disclaimer. Almost every open source license states that the software is provided "as is" without warranty. This is not just a courtesy; it is a legal shield. But the disclaimer only works if the license is properly applied. If you distribute the software without the license text, or if you modify the terms, the disclaimer may be invalid. I have seen projects accidentally remove the warranty section when copying a license file. That mistake can expose users to claims.
The third clause is governing law. Most licenses specify a jurisdiction, like California or New York. If your project is governed by the laws of a state you have never visited, you could be sued there. I once received a contribution from a developer in Germany, and the license specified California. If a dispute arose, I would have to defend myself in a foreign court. This is rare, but it happens. Some maintainers now add a choice-of-law clause in their CONTRIBUTING file to avoid this.
A real example: a friend who maintains a GPL library received a demand letter from a company claiming the library violated a patent. The letter cited the GPL's termination clause, which says that anyone who distributes GPL software and violates its terms loses their license. The company argued that the library's use of a patented algorithm without permission triggered termination. The dispute settled quietly, but it cost my friend thousands in legal fees. Most disputes settle without court, but the cost alone can crush a solo maintainer.
What I Learned from the EU Digital Identity Wallet Debate
In mid-2026, a discussion on Hacker News highlighted the EU Digital Identity Wallet's age-verification technical specification. The specification, hosted on GitHub, proposed that wallets must run on either Android or iOS, effectively locking out other platforms. Commenters noted that the license terms of the specification could force implementers to use only those operating systems. This is contract law meeting platform lock-in: by imposing license conditions, the EU could mandate technical choices.
The debate reminded me of a near-miss in my own package. Early on, I considered adding a clause that the library could only be used on Apple platforms. I thought it would protect the user experience. But a contributor pointed out that such a clause would make the license non-standard and potentially unenforceable. I dropped the idea. The EU wallet spec eventually added a clause allowing alternative implementations, but the controversy showed how license terms can become regulatory tools.
Open source is increasingly used as a compliance mechanism. Governments and corporations publish specifications under open licenses, and those licenses carry obligations. For maintainers, this means that the legal context of your project can shift based on who adopts it. A library written for hobbyists might end up powering government infrastructure. The license you choose today affects that future use. I now include a note in my README that the package is intended for general use and not specifically designed for regulatory compliance.
The EU wallet debate also highlighted the tension between open source ideals and practical governance. The specification was open for comments, but the license terms were drafted by lawyers, not developers. As a maintainer, I learned to read proposed license changes with the same scrutiny I apply to code changes. I also learned that the best way to avoid platform lock-in is to keep the license as permissive and neutral as possible. My package uses MIT, which imposes no platform restrictions. That simplicity is a feature.
Practical Contract Hygiene for Solo Maintainers
Disclaimer: I am not a lawyer, and nothing in this section constitutes legal advice. You should consult an attorney for your specific situation.
After my legal scare, I adopted a set of practices that I call contract hygiene. First, every project must have a CONTRIBUTING file that explicitly states the license terms and the process for accepting contributions. I include a line that says: By submitting a pull request, you agree that your contribution is licensed under the project's license and that you have the right to submit it. This creates a simple contract between contributor and maintainer.
Second, I use a standard CLA template. The Apache Individual Contributor License Agreement is widely recognized and covers patent grants and representation. I do not write custom CLAs; they are harder to enforce and scare contributors. A standard CLA signals professionalism. I store signed CLAs in a private repository as a paper trail. So far I have only a dozen signatures, but for critical contributions, it provides legal clarity.
Third, I pin governing law to my home state. In the CONTRIBUTING file, I add a sentence: This project is governed by the laws of Japan, where the maintainer resides. This is not a formal choice-of-law clause, but it establishes a default. If a dispute arises, the jurisdiction is clear. I also include a note that the project is provided "as is" and that the maintainer is not liable for damages. This mirrors the standard warranty disclaimer.
Fourth, I keep a paper trail of all contributor agreements. For significant contributions, I ask the contributor to acknowledge the license terms in the pull request comment. I also run automated license header checks in CI. A simple script verifies that every new file contains a license header matching the project's license. This catches accidental inclusion of incompatible code. The CI step takes seconds but has flagged several problematic contributions.
Finally, I review the license of every dependency added to the project. I maintain a spreadsheet of direct and transitive dependencies and their licenses. If a dependency uses GPL, I do not include it in an MIT project. If it uses Apache 2.0, I ensure the attribution notice is preserved. This diligence is tedious, but it prevents the kind of incident that triggered my first cease-and-desist.
When Offloading Thinking to AI Blurs Liability
An article on Artfish from July 2026 asked whether we are offloading too much of our thinking to AI. For open source maintainers, the question has a legal dimension: who owns AI-generated code contributions? If a contributor uses an AI tool like GitHub Copilot to write a patch, the copyright status of that patch is uncertain. The AI model may have been trained on GPL code, and the output could be considered a derivative work. As a maintainer, I could be distributing code that carries hidden license obligations.
I have a policy: contributions must be human-reviewed and the contributor must attest that they have the right to submit the code. I do not accept AI-generated patches unless the contributor explicitly states that the output is original and not derived from copyrighted training data. This is a conservative stance, and it may be overly cautious. Some projects welcome AI assistance. But until the law clarifies, I prefer to err on the side of legal safety.
The license compatibility of AI training data is a growing concern. If an AI model was trained on code under GPL, its output may be considered a derivative work under the GPL. Lawyers are still debating this. The Free Software Foundation has not issued a definitive opinion. For now, I include a disclaimer in my CONTRIBUTING file: Contributions generated by AI tools must be accompanied by a statement that the output does not infringe any third-party rights. This is not legally binding, but it creates a record.
Contract law has not caught up with AI. The standard CLA templates assume a human author. There is no checkbox for "generated by a neural network." Until the law evolves, maintainers must hedge. I add a note that the project accepts contributions under the terms of the license, and that the contributor bears responsibility for the originality of the code. This shifts some risk back to the contributor, though in practice enforcement is unlikely for small projects.
Six Years In, I'm More Engineer Than Lawyer
Contract law taught me discipline, not fear. I still write code most weekends. The package still ships new releases, and contributors still submit patches. But I now approach each pull request with a legal checklist alongside my technical review. That checklist takes maybe five minutes, but it has prevented at least two potential disputes. The trade-off is that I spend less time on features and more on documentation and governance. For a solo maintainer, that is a real cost.
Good governance reduces friction, not fun. When contributors know the rules, they are more confident. I have seen fewer questions about licensing since I added the CONTRIBUTING file. Technical decisions often have legal or contractual implications, as seen in articles like Service Mesh Overhead and Cross-Platform Library Bans. The same is true for open source governance.
That said, I also recognize that most maintainers never face a legal issue. Over-engineering governance can harm community contribution. If you require a signed CLA for every typo fix, contributors will go elsewhere. There is a balance. For BarcodeKit, I only require CLAs for significant contributions—those that add new features or modify core logic. Small bug fixes and documentation changes are accepted without a CLA, trusting that the contributor has the right to submit. This pragmatic approach has kept the contribution pipeline flowing while still protecting the project's legal interests.
I am still more engineer than lawyer. I do not give legal advice. But I have learned to read contracts the way I read code: looking for edge cases, undefined behavior, and hidden dependencies. The skills transfer. Version control teaches you to track changes; contract law teaches you to track obligations. Both are about managing complexity over time.
Next, I want to mentor other maintainers on legal basics. I have started a small guide on my GitHub profile, covering CLAs, license compatibility, and AI contributions. The goal is not to make everyone a lawyer, but to reduce the number of maintainers who learn about contract law the way I did: through a cease-and-desist email. The open source ecosystem runs on trust, but trust works best when backed by clear terms.
Still, I wonder: as open source becomes more formalized, will we lose the informal, collaborative spirit that made it special? Or can we find a middle ground where legal hygiene supports rather than stifles contribution? I do not have the answer, but I am watching how projects like Rust and Kubernetes handle these tensions. For now, I will keep coding, keep reviewing, and keep reading those license files—one clause at a time.