Skip to content
Featured Article

Artwork: Susan Haejin Lee

How ‘open’ should your open source be?

Boundaries aren't always intuitive for maintainers, but limiting contributions can be their healthiest option.

Mike Melanson // May 9, 2023

The ReadME Project amplifies the voices of the open source community: the maintainers, developers, and teams whose contributions move the world forward every day.

For all intents and purposes, the Litestream project is (and always has been) 100% open source. It satisfies all 10 requirements of the Open Source Initiative’s (OSI) open source definition, uses an OSI-approved license, and you’re more than welcome to fork it and modify it however you wish. There’s just one catch: For some time, the project didn’t accept code contributions of any kind.

But why, you might ask? One of the top reasons for making something open source, after all, is to receive contributions. Why even go the open source route if you're not going to accept code?

Litestream maintainer Ben Johnson closed the project to contributions in January 2021, explaining in a section of the README titled “Open-Source, not Open-Contribution” that dealing with even small code contributions was too time-consuming.

“As the author of BoltDB, I found that accepting and maintaining third-party patches contributed to my burn out and eventual archival of the project,” he wrote. “Even small contributions typically required hours of my time to properly test and validate them. I am grateful for community involvement and when folks report bugs or suggest features. I do not wish to come off as anything but welcoming, however, I've made the decision to keep this project closed to contribution for my own mental health and long-term viability of the project.”

While Johnson’s approach is a bit out of the ordinary and may call into question some assumptions about what is or isn’t open source, it also illustrates that open source isn’t one size fits all. Some projects accept contributions with relative abandon, while others employ lengthy lists of requirements and detailed processes, and others still opt to take code from just a select few. As an open source maintainer, the ongoing burden of bug fixes and feature requests require consideration. Simply turning off all contributions might feel like an easy escape, but it can be limiting in other ways.

We’ll come back to Johnson and his unorthodox method a little later. First, let’s take a look at how we got here.

Open source eats the world (and needs some Tums)

Early software was written by researchers and academics, and open by default—it couldn’t even be copyrighted until 1974. We didn’t even have the now-common phrase “open source” until Christine Peterson coined it in 1998. That same year, the OSI formed and established the aforementioned open source definition, which remains the yardstick by which openness is judged today.

For many of those early years, tedious and time-consuming methods such as email lists were the de facto standard for open source collaboration. Git, the open source distributed version control system created by Linus Torvalds, didn’t arrive until 2005, and even then it only offered a tool based in the command line. Three years later, GitHub offered a user-friendly interface for Git and introduced the pull request, a feature that changed the way maintainers manage patches in open source, which some might argue lies at the core of open source’s recent success. 

“One of the amazing things that GitHub did was make contributing easy and accessible. That has brought so many more people into open source, and it's wonderful,” says Julia Ferraioli, an open source advocate and software engineer. “On the flipside, it's also made it very easy to make demands without context.”

With that ease of access, open source projects can experience their own form of the Slashdot effect, where sudden popularity can be overwhelming for the lone maintainer. 

“As soon as you get noticed, you essentially have an unlimited number of stakeholders,” says Ferraioli. “You’re suddenly plunged into project management, diplomacy, marketing, and branding.”

We want to hear from you! Join us on GitHub Discussions.

Ferraioli argues that the knee-jerk reaction you might’ve had to Ben Johnson closing off his project to code contributions is less about the actual definition of open source, but rather the social model that has evolved over time. While the OSI definition offers 10 concise characteristics, those practicing and participating in open source often assume that open source software should be open to contributions from the community, welcoming to discussions around a project’s direction, and willing to accept new developers and maintainers. 

“There are plenty of open source projects that people generally don't consider open source because they're not building a community or making a lot of updates, but open source isn't just about contributions. It's about learning, understanding, and teaching, too” says Ferraoili. Research projects, she notes, are open source partly to allow third parties to independently verify their findings. By their nature, they can’t accept contributions of any kind.

“They're still open source,” contends Ferraioli. “They have immense value. People can learn from them, modify them, fork them. There are so many reasons they’re still wonderful examples of open source software, and I think we're quick to dismiss that.”

Beyond open source research, however, some open source projects choose to limit contributions for other reasons. 

Open source, but closed to contributions

The Lua programming language has been open source since shortly after its debut in 1993, but has remained closed to outside code contribution the entire time. Lua prioritizes speed, portability, simplicity, and small binary size, and it has found considerable popularity in the realms of embedded systems and game programming. The language was created by a team of three people, but for the overwhelming majority of its life, it has been primarily developed and maintained by Roberto Ierusalimschy, who makes it abundantly clear that, while he wanted the project to be open source so that anyone could use it and have access to it, the social norms around open source software were not a priority.

For Ierusalimschy, it’s not that he previously dealt with the problems of success in open source and decided to opt out. “We didn’t have this concept that open source software meant being open to developers,” he explains. “We thought that maybe other people would want to use our software, so we gave it a liberal license. We never thought about how other people might want to contribute.”

In much the same way that Johnson stopped accepting code contributions for Litestream, Ierusalimschy says that code contributions were the least of his concerns. “People always want to send code,” he says. “I always joke that code is the easiest part. I want you to justify why an idea is good, to offer a good explanation.”

Ierusalimschy points to the project’s goals as the primary reason for him to remain the sole code contributor. “One of the main selling points of Lua is that it’s very small,” he says. “It’s difficult to keep something small when everyone wants to contribute something new. It’s the committee effect: Everyone wants their idea to be in the language, and then later they can say ‘I gave that idea to the language.’ Nobody is ever going to say ‘I was the one to remove that from the proposal to keep the language small.’”

While Lua doesn’t accept code contributions, Ierusalimschy says that the community has inspired various feature additions over the years and helps with tasks like testing the language for portability. “We love that people use all kinds of different machines,” he says. “One of the main points of Lua is portability, so when we release a beta version, we ask people to try it on their machines. It is very useful for tests.”

When closed isn’t all it’s cracked up to be

For Ben Johnson, it’s a bit of a different story. Johnson had already enjoyed some level of success in open source when he decided to close Litestream to contributions in January 2021. With BoltDB, Johnson had dealt with “people getting kind of feisty” around some pull requests and in the ensuing discussions. 

“People would comment about how they thought it should have been done, and I didn’t necessarily feel comfortable accepting their suggestions,” says Johnson. “There’s a lot of social pressure, sometimes. Being very clear upfront—I’m not taking anything—just makes it a little simpler.”

On the technical end of the spectrum, Johnson echoes Ierusalimschy’s sentiments around code contributions. “I don't even find the actual code itself to be that hard,” says Johnson. “Only five percent of the effort to actually get something shipped is writing the code for it. It's the years of maintenance afterwards, fixing bugs, writing documentation, making tutorials, and all this other stuff. That’s the hard part.”

Johnson also points to Litestream’s technical complexity as further reason to limit code contributions. “People would submit feature requests and, even though it might be a fairly small feature, testing a database on edge cases really sucks,” explains Johnson. “It was a huge liability with every feature that came in. I just didn't have the bandwidth or the energy to take everyone's features and figure all this stuff out.”

Shortly after closing the codebase to contributions, Johnson added a section to the README to acknowledge that, “Many of the most valuable contributions are in the forms of testing, feedback, and documentation. These help harden software and streamline usage for other users,” he wrote.

By now, you might wonder: Why doesn’t Johnson simply ask for help from the community at large? After all, that’s how many projects handle bandwidth issues: They expand the team of maintainers, join a foundation, or create a business model around the project to meet the demands of success.

“I like working on my own,” explains Johnson. “Adding people changes it from a technology problem, which is why I got into software development in the first place, into a people problem.” 

A "Grand re-opening" sign.

In the end, however, Johnson found that remaining fully closed meant missing out on some benefits, and after nine months, Johnson changed the policy, ever so slightly. Acknowledging that his previous policy was “overly broad and has prevented small, easily testable patches from being contributed,” Johnson reopened Litestream to pull requests for bug fixes. 

Couldn’t those same lost benefits extend to other parts of the project, including the code itself, you might ask? This is where a maintainer’s personal goals also come into the equation. 

“With BoltDB, I was earlier in my career, so one of my goals was to increase my reach, get my name out there, and create a broader community,” Johnson explains. “With Litestream, I'm further in my career so that doesn't play into my goals as much. I work on Litestream because I like the challenge and exploration of working in an odd niche. I hope the tool provides value to the world, but I'm not interested in the recognition side of it anymore.”

Finding the balance between open and closed

While Johnson may not be interested in adding maintainers because of the “people problem,” this remains a common, yet not foolproof, solution, as Bartek Plotka related in his talk, “Should I merge this feature?” at the 2021 Global Maintainer Summit. Plotka is one of several maintainers for the Prometheus and Thanos projects, among many others, and has been involved in open source since 2015, when he started as a contributor to OpenStack, Kubernetes, and Apache Mesos. During that time, he says he’s traversed the full spectrum of how open or closed he was to feature contributions. 

Plotka says he started out as an “inexperienced optimist” who, if given the keys to the kingdom, would have readily admitted coffee-making capabilities into Mesos. On a scale of one to 10, with one not accepting any pull requests and 10 accepting them all, Plotka put himself at a nine. As time went on, however, he saw that the cost of maintaining extra code was real, with new features introducing additional support burden, security issues, and potential stability issues, among other unknowns. By 2018, he had become a Prometheus maintainer and a “careful pessimist,” who now had real responsibilities to end users in production environments. He suddenly found himself at a three on that same scale.

“I was part of making key decisions, and we blocked almost everything,” says Plotka. “We thought we were doing this for a good reason: to stabilize the project, not confuse people, and best support our users.”

The only problem, says Plotka, was that limiting code contributions came with its own, separate set of problems. For a project like Prometheus, which relied on a full team of maintainers to keep everything moving, blocking contributions meant limiting the supply of new maintainers to choose from.

“Many maintainers change their jobs, retire, or lose interest in projects, so it's key to mentor and add more members to the team,” says Plotka. By blocking too many ideas, Plotka says they were demotivating potential contributors and discouraging everyone from proposing changes. “Failing in the first interaction damaged how the community of potential developers perceived the project and future relationships,” he says.

After a couple years, Plotka says he and the Prometheus team found a middle ground, putting him at a six—a “realistic helper”—on his scale of openness. Instead of taking a default open or closed stance, Plotka says he tried to empathize with users’ problems to help them find feasible solutions. The move was a game-changer that allowed the project and its community to grow and flourish. At the same time, enthusiastically accepting contributions still posed the same risks as ever, so he came up with some technical solutions that help to mitigate the risks.

For example, hiding experimental features behind feature flags allows end-users to opt in to new functionality, ensuring that their experience isn’t broken by additions. Providing stable APIs for your project further allows developers to integrate with it and build add-on features via integrations that don’t need to be maintained and supported in the core project. Plotka also recommends providing integration documentation and compliance tests to ensure that any third-party integrations work well with your project. Finally, he suggests having a process around accepting or rejecting feature pull requests, with a focus on “unblocking” them.

“Your default response to accepting features should be ‘no,’ but ‘yes’ to unblocking potential contributors. Try to understand what problem they are trying to solve, put yourself in their shoes and work towards a solution. The solution might be merging the change if there is no better way, but it might also be suggesting something the user didn’t think of yet,” says Plotka. “Try to never just say ‘no’ without reasoning.”

The reality is, our assumptions around openness in open source are often overly idealistic. Open source projects commonly impose contribution restrictions, depending on characteristics like complexity, size, criticality, or otherwise. For example, many open source programming languages have lengthy feature proposal processes, not to mention restrictions on actual code contributions themselves. While a small frontend library may be relatively open to contributions, a project like Kubernetes sets a much higher bar—but not so high that it can’t boast more than 35,000 contributors. Most projects, however, find themselves somewhere in the middle of this spectrum of wide-open to completely closed.

Reconciling assumptions with reality

In some ways, the most unorthodox thing about Johnson’s decision may not be that he closed off his project to code contributions, but that he clearly communicated it—something that received a good bit of attention at the time. Ferraioli suspects that there are many more projects silently following a similar path.

“It's perceived as a hostile action, as opposed to setting boundaries for yourself, which is healthy. We should encourage people to be transparent about not having the capacity to accept contributions. Instead, people just silently refuse to accept contributions without that explicit communication,” says Ferraioli. “Somehow, that’s better in people's minds than being upfront about it, and that's a shame.”

She offers a model for how to communicate the state of your open source project that gives maintainers nine suggested “states,” such as actively in development, paused, stable, or relinquished, to clearly communicate a project’s current status and set expectations for end-users and potential contributors. If we look at Ben Johnson’s archived BoltDB project, for example, we find Johnson’s lengthy explanation in the README.md. “Bolt is in a stable state and has years of successful production use. As such, I feel that leaving it in its current state is the most prudent course of action,” he writes, referring users who desire “a more featureful version” of BoltDB to bbolt, the CoreOS fork of BoltDB. Under Ferraioli’s proposed framework, Johnson might simply label the project as relinquished and let that be that.

Project status is just one realm where open source projects and their maintainers could benefit from better communication. Shawn “Swyx” Wang, writer and editor at DX Tips, proposes a method for breaking apart the maintainer monolith, where communication focuses instead on the needs of the project rather than its status. Wang focuses on the delta between social norms around open source and the on-the-ground realities.

“People default to the benevolent dictator for life (BDFL) model, where the authors are responsible for everything. That’s causing a lot of burnout,” says Wang. “The way that we behave is very much a result of the norms that we see around us, so in order to change our behavior, we have to change the environment that we're in.”

Wang’s suggested change involves the creation of a file—MAINTAINERS.md, for example—that provides a structure for people to become involved in a project without taking on the current status quo of lifetime appointment.

We want to hear from you! Join us on GitHub Discussions.

“If this is a social problem, then we have models that are a bit more time tested in human history. We can study them, bring in that expertise, and explore other forms of governance,” says Wang. For example, just as many roles in public life are term-limited, contributors could join open source projects for a set period of time, rather than feeling like they’re on the hook indefinitely. 

“I think a lot of people simply opt out of open source altogether, because of the perception that lifetime appointments are the norm,” says Wang. “Instead, let's restructure the social contract so that the burden is not so high and increase the total available amount of open source. Let's make existing successful open source projects more successful by improving the governance model.”

About The
ReadME Project

Coding is usually seen as a solitary activity, but it’s actually the world’s largest community effort led by open source maintainers, contributors, and teams. These unsung heroes put in long hours to build software, fix issues, field questions, and manage communities.

The ReadME Project is part of GitHub’s ongoing effort to amplify the voices of the developer community. It’s an evolving space to engage with the community and explore the stories, challenges, technology, and culture that surround the world of open source.

Follow us:

Nominate a developer

Nominate inspiring developers and projects you think we should feature in The ReadME Project.

Support the community

Recognize developers working behind the scenes and help open source projects get the resources they need.