The value of "small" contributions

MP #25: In appreciation of first-time open source contributors.

I’m spending this week at the PyCon US 2023 sprints. If you’re not familiar with sprints, they’re a chance to stay a few days longer at a conference and work on open source projects in person. Sprints are a fantastic way to get some in-person time with people you usually only work with remotely. Sprints are also a great way to bring new people into open source, and experienced people into a new project.

Over the course of several sprints, I've found that new contributors often vastly underestimate the value of their “small” contributions, in particular to a newer project. Initial contributions to a new project are often one-line fixes, but there are significant, mostly invisible contributions that go along with the code that’s added to the project.

Hosting a sprint

When I first started attending sprints, I worked on my own small projects while watching people work on larger, more established projects. I was mostly interested in seeing how people work collaboratively on large projects that have lots of different things going on.

These days I have a growing open source project, so I host a sprint. I’m working on django-simple-deploy, a tool that lets you deploy Django projects to the platform of your choice in just a few simple commands. I spoke about the project at DjangoCon US 2022, and it was well received because the project solves a longstanding pain point in the Django world: How do you help people carry out their first deployment without getting so lost that they abandon their project?1 Development has been mostly quiet so far because the project is still in the pre-1.0 phase The goal of this week’s sprint is to get the project as close as possible to 1.0, for an anticipated 1.0 release this summer.

Placard on a tabletop reading "Ask me about django-simple-deploy!"
A simple invitation generates a lot of fun and helpful conversations. :)

“I’m just here to help for a little bit”

Matt sat down and introduced himself, saying that he didn’t know anything about the project but he was happy to help for a bit. Before hosting my first sprint for simple_deploy last fall, I added a section to the Contributing docs that introduces people to the project. The basic idea is to have people use the project once, either deploying a project of their own or a sample project, while capturing all of their initial reactions to the project in an issue structured to capture this feedback:

After you complete the test run, please answer the following questions in a followup comment:
  • What worked well? What didn’t work well?
  • What suggestions do you have for the project based on your test run?
  • What questions do you have about the project based on your test run?

This approach to onboarding new contributors works just as well for people new to open source as it does for people who have led major projects on their own. It works for people who have struggled with Django deployments, and it works equally well for people who know way more about deployment than I do. Each person brings their own perspective to the project, and this onboarding approach captures valuable feedback from all kinds of users.

Sitting next to Matt while he went through this process was invaluable to me as a maintainer. I usually have a working version of the docs open during sprints, so I clarified sections of the documentation based on our conversation, while we each worked. Matt’s initial deployment using the project surfaced an issue with the automated configuration for Heroku deployments. It was an issue about which version of the psycopg2 package currently works on Heroku. The fix is a one-line change to how the psycopg2 requirement is added to the user’s project:

Screenshot showing a one-line GitHub PR.
Matt’s PR, fixing an issue with Heroku deployments.

The basic fix for this issue is to remove the version="<2.9" argument from the line that adds psycopg2 to the project’s requirements. This fix hasn’t been merged into the project yet, because if Matt is interested I’ll walk him through the rest of the process: updating the unit tests, running the integration tests to see if this issue affects other dependency management systems, and making appropriate changes.

Matt, like other first-time contributors I’ve met, had an understandable inclination to downplay this contribution. I read through the error logs in the output of his test run, replicated the issue on my laptop, and then troubleshooted the issue quickly because I’ve read through a thousand Heroku error logs over the years. It’s easy for someone in Matt’s shoes to think, “I really didn’t do much here.” But, the important thing to realize is the value of all these conversations about a growing project. For a whole day I’ve had a fresh, inquisitive, appropriately critical set of eyes on the project’s documentation, deployment process, and finally the codebase itself. This is an invaluable contribution to a pre-1.0 project.

“I really enjoy making contributions to projects”

Marco showed up at one point and said he was interested in the project, and really enjoys jumping into a variety of projects and making contributions. He is fluent with the entire open source toolchain, and knows the workflows well. He ran through the documentation for deploying to Fly.io, and immediately noticed that my documentation uses the command fly, while the official Fly.io documentation uses the command flyctl. I know these commands are interchangeable, but to someone new to this project it immediately makes them wonder if they’re doing something wrong.

Being comfortable with the open source workflow, Marco quickly made a PR, and the project’s documentation is better:

Screenshot of Marco's clarification in the documentation.
Marco’s contribution clarifies the equivalence of the fly and flyctl commands.

One thing I really appreciate about Marco’s approach to contributing is the details he includes in a PR. He added links to some discussions in the Fly.io forums clarifying that they are moving towards using the fly command, and eventually deprecating the flyctl command. These details can seem unnecessary to include in such a “small” PR, but these are in fact the kinds of details that save long bike shedding discussions later about which of these commands to use in our docs. It saves us from having to do the same documentation and forum dive that Marco did yesterday.

“I never download a binary!”

Marco also said something that caught my attention as we were working. He hadn’t used Fly.io before, so he had to install the Fly CLI. I always approach this by following the simplest instructions on the platform’s documentation. Marco laughed as he was reading the Fly documentation and said, mostly to himself, “I don’t download binaries!” I asked what he meant, and he said he always compiles binaries from source. I am familiar with this process, but I’m at a point where I’m happy that someone has created an installer and I don’t have to compile from source often.

This is another “invisible” contribution that happens at sprints. I know for a fact, just from this two-minute conversation, that Marco knows more about installing from source than I do. He almost certainly knows more than I do about dealing with obscure compatibility issues with binaries, and more complex packages. Even if Marco never seeks out a contribution to this project again, I know that I can reach out to him if I have a question in this area. These are the kinds of connections people make at in-person sprints, that are simply impossible to capture when working remotely.

Conclusions

It’s perfectly understandable why people have a tendency to downplay their small initial contributions to open source projects. However, especially for a growing pre-1.0 project, there are many invisible benefits of a contribution that go well beyond the number of lines of code in a PR.

If you’ve been hesitant to get involved in open source because you feel you won’t be able to contribute much, consider finding a smaller, growing project in an area you’re familiar with. Your contributions will be invaluable. If you have the chance to attend an in-person sprint, go for at least a day and meet some of the people doing this work.

Thank you to everyone who makes time to start out with a small contribution. Your efforts are deeply appreciated!


  1. People often think django-simple-deploy is primarily aimed at beginners. That’s not the case at all; this is a perfect example of how serving beginners well often times ends up serving experienced developers as well.

    For example, imagine someone who is very experienced at deploying Django projects to well_established_host. They want to try deploying to shiny_new_host. Instead of combing through the documentation for shiny_new_host and trying to get the configuration right, they just run simple_deploy against their project, targeting shiny_new_host. They immediately have a working deployment, and all the configuration for that platform is contained in a single git commit. This is a huge timesaver, and lets experienced people easily explore a variety of platforms.

    For more non-beginner use cases, see Use Cases in the documentation.