This article is the second entry in a two-part series. In the first post, I went over the early history of Snowpack and how we grew an open source project to find our first set of users. In this post, I want to focus on what happened next: how do you maintain and continue to grow a large project at this scale?
This will be an entertaining read for anyone interested in open source software. The highlighted lessons are for current (or aspiring!) open source maintainers of large and/or growing open source projects.
If the first post in this series was about everything that I did right with Snowpack, then this post is about everything that went wrong.
When you do something like this for the first time, you're never going to get it 100% right. This was my first experience maintaining an open source project of this scale. I had started plenty of new repos in the past, and some of them were even well liked, but none had ever grown this big. We didn't have a roadmap for this transition, and I made plenty of mistakes that I now see in hindsight.
I want to make it clear that I'm incredibly proud of this project and the people who have contributed to it. Snowpack pushed the entire web development industry forward, and that's pretty cool. Even if you never use Snowpack directly, the work that we pioneered -- specifically around npm package handling for ESM and unbundled development -- is being built on and improved on across the entire web tooling landscape in projects like Vite, Skypack, JSPM CDN and others.
This post is my attempt to create a guide for anyone who finds themselves in a similar position one day.
Real-world testing is super important. I'm sure that sounds cliche, but its true. We had a few starter projects that we could test Snowpack against, but they were all small and simple. This created a huge experience gap between our internal projects and our actual users.
People tend to think of "dogfooding" as a way to prevent bugs, but I've found it to be most useful as a way to align with your users. It's impossible to make good decisions about something that you don't know well. Without some kind of real-world dogfooding, you often end up prioritizing the wrong features and fixes.
This is unfortunately one thing that large-scale corporate open source does well. Facebook is able to test a new React feature or bugfix across a codebase of 30,000+ components. They can try things out internally, at scale, before sharing publicly.
If your project isn't owned by a tech giant, you still have options. If you work somewhere full-time, try to dogfood things within your company. Rich Harris often talks about how using Svelte at The New York Times benefits the framework. Your company could be a real-world playground for new features, API changes, and even entire pre-release projects.
Snowpack never had a company playground. Yet, we still could have been better about talking to our users and getting feedback before working on features. In retrospect I would have sought out invites to real-world codebases in exchange for some testing and support.
Lesson: Dogfood large projects to prevent bugs and useless feature work.
In the early days of a project, you'll be forgiven for a few bugs and odd behaviors. As your project matures, this patience tends to run out. The real problem doesn't have to be a single big bug, but the sum of multiple "poor" user experiences.
For example, you should always have a clear error message when something breaks. Yes, even if you think that it was the user's fault:
As our audience transitioned from early-adopters to a larger "mainstream" audience, users became less likely to track down odd errors (
undefined is not a function 😱). Instead, they would abandon the project for more familiar/stable alternatives.
This is also relevant to how you choose new features. "Bundling should be optional" was a core idea baked into Snowpack from the start. If you remember back to the first post in this series, that was the idea that our first users fell in love with. As we grew, mainstream users didn't love it so much. They were mostly confused why they had to implement such a simple feature themselves.
Lesson: As your audience grows, understand how your users change. Invest in testing, clear error messages, and overall stability. Make sure that the default user experience is good before investing in advanced features.
Snowpack almost powered SvelteKit.
Rich Harris announced it at the Svelte Summit conference, and published a blog about how excited he was about our project. We were ecstatic. But right before SvelteKit's public release, they switched out Snowpack for an alternative tool called Vite. We found out tool late. The decision had already been made. Their team was unhappy with Snowpack, and we hadn't even noticed!
You tend to have a strong connection to your users on smaller projects. But as the audience grows, you lose touch a bit. I had gotten so used to this feedback cycle that I hadn't even thought to check in. I had missed the rough edges that the Svelte team was encountering every day, and only got their feedback after it was too late to change any minds.
It's important for open source leaders to invest in feedback channels. We learned this too late.
Lesson: Don't wait for your users to tell you what's wrong. Be proactive about gathering feedback and fixing issues.
The best part of open source development is the community. As your project grows, you'll see more people stopping by to chat, comment on issues, and maybe even contribute some code. Repeat contributors can become life-long friends.
Consistency is the best way to build trust in your community. Bursts of productivity are fine for personal projects, but the long stretches of quiet that usually follow are poison to a growing community. This might be the most common mistake that I see large open source projects make. When you step away from your project, contributors and potential future contributors notice. There's nothing worse than putting time into a PR and then having it sit around, uncommented and unnoticed for weeks or months.
I want to stress that the solution here is not "just spend more time." That's a guaranteed path to burnout. Instead, spend your time better. It's better to spend an hour or two every week than it is to spend a full day, once a month.
For what it's worth, this is something that I'm still working on myself.
Lesson: Be consistent. Don't leave your contributors hanging on code reviews and pull requests.
I mentioned it before but it's important enough to say again: Use Discord. Create a community server as soon as your get your first users. If you already have a Slack community, start thinking about moving. Seriously, it's that much better.
A new Discord server will only ever be as active as you are. If you never visit it, don't expect much to happen. If people never get a response, don't expect them to stay for long. Calling back to the previous two sections: Consistent presence is the best way to build a community and get valuable feedback from your users.
Discord also is great at encouraging experimentation. Is someone recommending a great bot (aka integration) for your server? Try it out! Ask them to help integrate, customize, or even teach you how Discord works. If your codebase is daunting, Discord can be a great middle-ground where you can collaborate with (and even learn from) your community.
Lesson: Use Discord. Be present + consistent. Embrace the fun side of the platform (emotes/emojis, bots, stickers, etc).
It's important to realize when your project has grown beyond your ability to maintain it alone. At that point you'll have a decision: bring on more people, or burn out.
"It will just be faster if I do it myself" might be true short-term thinking, but its dangerous over the long-term.
Despite accepting plenty of contributions over the years, I still fell into this trap with Snowpack. A part of me wanted to run the project all by myself, and refused to encouraged larger contributions. I shipped some great stuff during that period, but I also rushed my work. Code quality suffered. I skipped code reviews because I felt I didn't have time for it. And then when I did step away to recover, I would stay away for longer periods and the project would go quiet.
Ever been so burnt out that you didn't have the energy to realize it? Yeah. It's tough.
Lesson: You can't do it all yourself. Building a community can be the most fun part of open source, if you invest in it. Read up on good open source governance to learn how others do it.
If you're currently an open source maintainer or contributor, I hope that you have found this honest guide useful! This last year has been a wild journey, but I wouldn't trade a moment of it.
Painful mistakes tend to stick. I've already started to apply these lessons to our newest project, Astro. We've already invested in an active Discord, a healthy governance model, a solid test suite, a focus on stability, and a community of amazing maintainers.
It's a great feeling to step away and know that your project is in good hands.
To be honest, I'm not sure where Snowpack goes from here. I burnt out on it at the end of last year, and haven't found the energy to return. Usage and downloads began to trend down and the community has gotten quieter.
At the same time, Vite (that Snowpack alternative that now powers SvelteKit) is taking off. To their credit, they do a lot of things really well. The good news is that two tools are very similar and easy to switch out. Even Astro is experimenting with moving from Snowpack to Vite in a future release.
So maybe it makes sense to wind things down. We asked our community if anyone wanted to get involved in long-term maintenance. But new contributor onboarding takes time that we just can't seem to find any on our end. It's a bit of a Catch-22.
One other idea would be going back to basics, and bring this story full-circle. The ESM package installer that our first users fell in love with still exists as its own package. The audience for a utility like that would be smaller. It might even be fun!
Whatever happens, I know that we'll keep learning and keep improving.