I want to wow people. I want them to say, “Whoa, I didn’t know that was possible.” With a computer, there are so many ways to do that. It’s like an idea machine without the limits of the physical world. Within a computer system, there’s the written rules—and then there’s a separate set of rules, which is the actual code. Whenever there’s a difference between those two sets of rules, that’s an opportunity to do something surprising.
At my last count, I maintain over 100+ projects on npm. A lot of those are small libraries, so it’s less impressive than it sounds, but it’s about 500 million downloads a month. I know automated systems install them over and over again, so even 500 million is a massive overestimate of the impact. But nonetheless, it’s humbling to think that if I screw this up, it’s going to affect many people.
To make it less scary, I remind myself that it’s open source: The MIT license literally says that the software is provided as is, with no warranties. At the end of the day, it’s a resource and a gift that I’m providing to the world, and people can take it or leave it. Just because I wrote this code doesn’t mean I promised anyone my soul for the rest of my life.
Building the LEGO blocks of open source
When people talk about decentralization, they often talk about the blockchain and cryptocurrencies. Before all that was a thing, the most popular decentralized network that existed was BitTorrent. Back in 2013, I started a project called WebTorrent to see if we could make BitTorrent accessible to web browsers. Instead of installing it on your computer, you can go to any website with our JavaScript library and join a big peer-to-peer network with access to all the information and files out there. That’s why it’s called WebTorrent: It’s BitTorrent for the web.
The JavaScript way to solve problems is to break it all down into modules. So while working on WebTorrent, I created many different packages that address subparts of the problem, including a code linter called Standard JS that took on a life of its own. Most of the downloads my software gets are from these smaller pieces. I would say almost every company uses my code in some way, since these smaller npm packages make it into everything. I don’t say that to brag—that’s just how modern software works. For example, I know Slack and Discord use my code because they post their thanks to all the maintainers they rely on, which is cool and something that more companies should do.
Some people trivialize these smaller packages, which are sometimes just 100 lines of code, but I don’t see it that way. When you solve a problem that’s lower on the stack, it’s often more useful to more people because it’s fundamental. One hundred lines doesn’t sound like a lot, but that could take someone a solid half day. Nearly every app is built on open source code: Each one is usually 90-95% open source, and the rest they wrote themselves.
One of the JavaScript packages I wrote is called buffer. Anyone who uses a package that was meant to run in Node.js but wants to use it in a browser context will pull in my buffer library as part of their process. So it’s on a ton of people’s websites, and there’s a code comment that notes that I’m the author, and includes my website URL. Sometimes, I’ll get emails with support questions from people saying they saw my name as a maintainer on some huge company’s website. So I have to say, “I was not involved in making that product. They just took my open source code and used it. My name ended up on their website, but I actually have nothing to do with building that website.”
When I first started, no one used anything I wrote. But over time I got better and made more useful contributions, and it was thrilling to see even one person use my code. When I reflect on what motivated me, it felt like I was contributing to the commons and advancing human knowledge. I felt like once I write this code, no one else will ever have to write it again. It’s a reusable piece of functionality, like a LEGO block that anyone can use to build bigger and fancier things.
When I run into a LEGO block that’s missing, I try to build one in a way that’s open source and reusable. When I’m done, I know I’ve contributed an additional LEGO to the world’s tool set. Anyone in the world can now grab that extra LEGO—and because of the way code works, there’s no cost to replicate it. I do the work once and humanity can benefit forever.
The challenge of making a living as a maintainer
When you write 100-line packages, it can be hard to get funded. They’re often used transitively by a project, which is used by another project, and so on, finally leading to a company who only knows that they installed some top-level package. There are actually five layers of other people’s projects below that and they might not even know you exist.
From 2015 until 2018, I worked on open source full time and lived frugally. In 2017, I was working on a music video browsing tool that was sort of like those pop-up videos for VH1. I needed a YouTube player component that could massage the rough edges of the YouTube API, so I took a half day and wrote a little component library called yt-playeryt-player yt-player. I published it, then went back to work. Before I was even able to start using the library I just wrote, I started seeing users open issues on yt-player. That’s when I realized there is a cost to open sourcing things: If I had just solved the problem for myself, no one would’ve been bothering me with issues and reporting bugs.
I really want to solve issues that have been opened by users, but I eventually realized I should focus on making things work for me first, because that was the whole point of writing the code. That’s when I started thinking about funding. I’ve long felt that open source maintainers should get paid for their work, and I’ve done a lot of experiments to try and figure out funding models for myself.
One was a project called funding, which allowed maintainers to show an ad in the terminal at install time. When someone installed a package using funding, they would see a message from a company sponsoring the package. With this project, I faced a big community backlash because people were upset to see ads in their terminal: It was the one sacred space that didn’t have any ads and I was trying to change that.
On the other hand, there was an equal number of people who were happy I had “poked the hornet’s nest” because there’s this massive entitlement in open source. Some people see it as a cornucopia of free projects. When something doesn’t work, they get angry and demand solutions. They don’t realize that the people on the other end are actually just volunteers working for free, in their free time.
Some maintainers are fortunate enough to be paid to work on open source full time. But a ton of others are just random individuals who found themselves maintaining something. Maybe they worked at a startup and created code while they were there, and then they left—but they’re still responsible for that code. When they see that lots of companies depend on it, they can feel an obligation to keep it maintained even though they may be working somewhere else and can only do that after hours. So even though that experiment wasn’t received well by some in the community, it forced a conversation about where open source comes from and how maintainers make (or don’t make) a living. The conversation around how to best sustain open source continues to this day.
The thing I found most effective in terms of funding was support contracts. In my case, WebTorrent is used in a high-value way by a web browser company called Brave. So I asked if they wanted to sign up for a support contract which entails me to work a certain number of hours a month on whatever issues may come up. This way, I can charge them a meaningful amount of money instead of trying to get one to five dollars from a bunch of different individuals.
Learning in and outside the classroom
In 2018, I went back to school to get my Master’s degree in computer science at Stanford. Working on open source is almost as good as getting a Master’s because you work on real code and real problems and deal with all sorts of different people. But there are certain things you can only learn at school. I’m not going to open a textbook about cryptography on my own and read it. If you’re in a class for 10 weeks and have all these readings and assignments, you get structure.
I really recommend people get a Master’s degree if they’ve already been in the industry for a while. Before my Master’s, I’d run into things all the time—such as how a cryptographic hash function actually works–that I wished I could dive deeper into but never had the time or opportunity to dig into. Going into a Master’s with that context, you’re motivated to figure it out. If I had gone straight to a Master’s after undergrad, I’m not sure I would have known what to pay attention to. I don’t know why we jam so much schooling early on, and then you don’t take any more classes after you’re 22. It should be spread out throughout your life.
It’s actually really hard, but fun, to teach. While I was doing my Master’s, I got asked to teach a class on web security. Most people don’t consider anything except getting their code to work. So we pull the curtain back and show what happens if you code without thinking about security. It was a lot of fun to teach. I also put all the materials for the class online for free for people to access. The course videos are on YouTube.
After getting my Master’s, I founded Socket, a new effort to defend the open source ecosystem from supply chain attacks. Together with a team of open source maintainers, we’re auditing every open source package to automatically detect suspicious changes and block supply chain attacks without slowing the development process. We are taking an entirely new approach to one of the hardest problems in security in a stagnant part of the industry that has historically been obsessed with just reporting on known vulnerabilities. Unlike other tools, we detect and block supply chain attacks before they strike, mitigating the worst consequences. By statically analyzing every open source package on npm when a new version comes out, we can see what changed between the old version and the new version. If something drastic changes, we can detect that. For example, if someone compromises a package and tries to add malware, it’ll start to download executable code from a random web server. We detect that.
Incorporating a release valve and empowering others
The number one thing that has helped me on my journey is collaboration. Collaborators have really saved all of the projects I’ve worked on. If you go out on a limb and trust your collaborators, it’s worth it, supply chain attacks notwithstanding! Moving projects from your personal name space into a GitHub organization is a good way to avoid being a bottleneck (or single point of failure) in the process. This way, if you end up being busy—say, to get your Master’s or start a new company—others who are invested in the future of the project are empowered to take over. There’s a release valve.
When I first started on open source, I didn’t intentionally think about how to build a community, but it happened by accident. I honestly just tried to be nice and model good behavior. When someone was “mad” about something, I’d try to get to the core of what they were saying. I wrote good comments in the code and somehow we ended up with a good culture on the WebTorrent project. Everyone’s on the same page even though we don’t really have meetings.
When you have an open source project, the people who are attracted to it are already thinking along the same lines as you. They self-select in a way. In recent years, I’ve been trying to be more intentional and organized with calls to discuss our goals and outstanding issues. I wish I would've done it earlier because I didn’t put a face to the name for a lot of the people who I worked with for way too long. And some of their GitHub pictures don’t tell you anything about who they are. I’m really glad that I know who lots of them are now and consider them friends.
I feel responsible for my code, but I also try to think about it in a healthy way. I think a lot of maintainers have this progression:
In the beginning, no one cares what you do or who you are.
Then you create something great and you’re happy anyone uses it.
More people start to use it, which is awesome.
Then too many people use it and there’s this huge burden of work.
You go into a burnout phase and feel bad if you can’t get to everything.
Then there’s the final phase, where I am now, which is when you realize everyone will be fine and you don’t have to close all your issues.
No software is perfect. If and when I can add other contributors who can pick up any slack, all the better. By building an open source culture and licensing it that way, you’ve given users the tools to fix their own problems. It’s not a proprietary product where people have to ask you for permission and you have to fix it for them. The code is there and they can see how it works and they’re free to fix their own bugs or add their own features. They’re empowered to do it. That’s the beauty, and the magic, of open source.