A Bitter Guide To Open Source
Hi. I’m Ken.
I’m the Director of Open Source at the best company in the world, Formidable.
If you’ve heard of me before, its probably for one of two things, or both:
- Talking a bunch of shit on Twitter
- Open source libraries such as Slick Carousel, Webpack Dashboard, Spectacle, Cash, etc…
Today we’re gonna focus on #2. I’ve recently (and historically) had a lot of people ask for guidance around Open Source, and today is the day I actually feel like writing.
Before we get into tips, I want to cover WHY you would want to do this, and my personal experience.
Why you should write OSS
As to the WHY, there are a ton of reasons why Open Source is a great thing for you and your career.
- It can do wonders for your personal brand. If you have a popular project, people will become familiar with you and your work
- It can do wonders for your company’s brand. Providing and maintaining an open source portfolio can give visibility to the brand. Giving employees time to work on this and see their ideas through can make it clear that it’s a great place to work
- You can grow as a developer! You aren’t just writing side project scripts that will grow cobwebs in your /Users/Me/devshit folder anymore. There are eyes on this shit, so theres motivation to keep things tight.
- You are giving back. The same way you saved time on that project because John-David Dalton dropped lodash, you might save someone else time with your code. You become part of a community where we all save time because we collaborate and share.
- It feels great. Speaking personally here, but it is truly an amazing feeling every single time someone thanks you for a project or tells you a story about the time you saved them.
- It might not get you a job, because most companies don’t hire strictly based upon GitHub stars, but I’d be a liar if I said it wouldn’t help get you an interview.
My experience with OSS
Lets just get this out of the way. I’m the worst Open Source maintainer in recorded history. Ok, maybe not the worst, but I haven’t done my best each time.
I have failed on a number of occasions to properly manage open source projects, but hot damn if I haven’t had a reasonable amount of success creating them.
But with each project, I’ve learned from my failures and walked away with insights that help me do better, and I’m going to cover those later. I’m certainly getting better at this, but I hope some readers can learn from my mistakes instead of doing it the hard way.
I’m choosing to write briefly about my experience, because compared to the typical OSS experience it’s sort of unconventional. Believe it or not, I think in my entire career I’ve probably made less than 20 contributions to projects that were not my own. I literally just write stuff and put it out. I think its important to cover, for perspective and context.
My first OSS project is probably my most successful project. I remember I was working at an agency, creating e-commerce sites for large fashion brands in NYC. I was a senior dev on the team, and I was typically pegged to do the heavy JS work. Journey with me back to the jQuery days…
Funny thing about fashion e-comm, there are carousels EVERYWHERE. They also tend to have elaborate, complex ambitious designs. It got to the point where existing carousel/slider libraries were not flexible enough to support the designs I was being given, so I started writing carousels from scratch, in CoffeeScript. It worked, but it certainly didn’t earn me any popularity points with my coworkers.
So I saw a clear need. A need for a carousel plugin that was flexible enough to support anything designers threw at us, easy to use, and easy to modify. So I wrote it. For us. And then I decided that it was so helpful, why not save everyone else a bunch of time, so I open sourced it…
Turns out it did save everyone else a bunch of time, and people seemed to like it. The first few months after releasing it, the popularity was through the roof. I was new to OSS, and so excited that people were actually using my stuff that I would stay up entire nights quickly fixing issues, pushing releases out and making sure no one could compete with it.
Cutting myself short a bit here, because this is an article on tips, not my life story: what eventually happened was I stopped caring. I chalk it up to a couple of things. I switched jobs, so I didn’t actually need carousels anymore, I was out of the problem space. React came out, and I got on it early, so I had no interest in jQuery stuff anymore.
But one of the biggest reasons was that I was burned out. I worked on it too hard. I read the comments, people were super entitled and opinionated, people whined about how we shouldn’t use carousels (even though every project for money I had done to that point had one, and I simply got handed designs), and I had fattened up and my wife was pissed off.
Since then, I’ve had several popular libraries in different spaces, each solving a different problem. One of my biggest fears is that I’ll never write a popular library ever again, that my hits are behind me. I’ve avoided it so far, and I’ve been able to consistently do reasonably dope shit, but one thing that will never stop bothering me is the feeling that I let half the internet down with the management of that damn carousel.
So here are my OSS tips, and hopefully you can use them and have successful projects, and not use whiskey to dull open source guilt.
Open source is a lot like giving talks. Many people don’t think what they are selling is valuable enough. And thats bullshit. If you read the stuff on imposter syndrome, its totally true. Every single person has their own corner of the knowledge pie, and no single person has the whole pie. There is always someone who needs what you are selling.
I have the distinct advantages of a) not giving a fuck and b) having a weird amount of unearned confidence, so I just put shit out, but I’ve noticed its hard for a lot of people.
Whats the worst that could happen? People are gonna talk shit? I got news for you kiddo, you could put out the most perfect, useful, fuckin mind blowing code that ever touched GitHub and guess what? Some asshole is gonna come in and whine about something. Its an inevitability. Worst case scenario, you learn something. Someone will be like, “Hey this makes performance suck” and you can either be like, “Ugh I’m bad at programming, I quit” or you can be like “Oh wow, thanks for the tip, just fixed it, now its better”. Be the person who makes it better.
So what should you build? Well thats the million dollar question right there!
I see it like this:
- You have a problem
- You have a solution to the problem
- You provide the solution wrapped up so nicely that people will want to use your solution to solve their problem with
So lets talk about how to wrap it up nice…
So you have your idea. You had a problem, and now you’ve solved it. But you want other people to use it right? Here are some tips on making other people want to use your shit.
First and foremost, have a look at competitors and prior art. If someone else’s library does the same thing yours does, you’ll need something that sets it apart. Lets say you want to build the next lodash. Good fuckin luck (sorry had to get that out of the way). But outside of that, in order to tap into lodash’s market share, you’d need to have a hook. It would have to be smaller, or faster, or a better API. See where I’m going with this?
Speaking of API design, there needs to be a balance. You could make a library that just works out of the box without doing anything, but then people will complain about wanting to tinker. You could make the most flexible, configurable library of all time, but then you would be Tobias Koppers/ Sean T. Larkin and people would complain about having to configure it (Sorry Sean, I had to. Great job on v4).
You want to find the perfect balance of working out of the box, and configuring as necessary. On top of that, you want to keep things clear, explicit and approachable. Don’t be too clever or you will piss everyone off.
One thing I like to do is to write my source in a way that is very explicit and not clever. It makes it easier to contribute to. Name things what they are, don’t do masturbatory functional programming, if you’re going to do a hack, put a comment in about why.
These days I don’t write a single line of code until I’ve done a mock fantasy API of what I wish it would work like. It changes over time when you have to make it real, but its a great target to strive for. You’ll know when the API is right because YOU will feel like using it.
Getting Ready To Release
So you’ve gone ahead, solved your problem, wrapped it up nice, and its ready to go. Now its time to release it. But before you do, there are some things that need to happen if you want people to use it.
WRITE SOME FUCKING DOCS.
I’m not kidding here at all. Your docs need to be the best docs ever written. Avoid saying condescending shit like “just” and “simply”. You need a header link index thing at the top. You need a getting started section that explains in excruciating detail how to get this running the first time. You need every nook and cranny of the API documented in ridiculous detail.
If you have a method, you should have the expected arguments, types and return types documented. You should document what it does. You should give an example of how to use it. Make it easy to use your library.
You should document how to contribute. You should document how to run all the build steps. If you reference another project, or a concept, link to it. If you reference anything linkable at all, link to it.
Be thorough, it will make a BIG difference.
WRITE SOME FUCKING TESTS.
Hear me out on this. You should have that shit covered, at a reasonable percentage. Heres why:
- It will inspire confidence in the health of your library
- It will let you confidently merge PRs
- It will let you confidently work on it after being away from the project for a while
One time I released a library, no tests, and Paul Irish chimed in and was like, “Would be cool if it had some tests”. Naturally, I was like, “Holy shit, its Paul” and went to write tests. I UNCOVERED LIKE 15 BUGS FROM WRITING THOSE TESTS! Thanks Paul!
If you do anything at all, write some god damn tests. Pretty please. With a cherry on top. It would have saved me so much time and grief.
And after you’ve written your tests, just set it up on Travis or whatever and then you can sleep at night.
Whatever tests don’t catch, types will. These days if you aren’t typing your JS, you are driving without a seatbelt on. Plus, with more and more people using TS or Flow, they are coming to expect that types are in place. Write your libs with types, export and provide the types, and thank me later. Or let somebody else type it later, third party style, out of date and probably wrong. Do whatever you want.
- A valid, filled out package.json
So README, duh. You should ALWAYS include a LICENSE.txt, or some people won’t be able to use your repo. Just do MIT. Don’t be cute with some self written bullshit license. Just MIT. Just do it.
CONTRIBUTING.md is a great place to not only specify how to work on the project, but link to/add your code of conduct. Add a code of conduct, whether you agree with the concept or not. Trust me. It will make some people feel comfortable contributing and participating and if you have a problem later, its a great sign to point at when giving unsavory individuals the boot.
So you’ve written great docs, API is tight, all the prereqs are in place and you are ready to make your repo super legit before releasing. I have some opinions.
Badges. Nothing makes your repo look more legit than badges. Too many badges looks memey as fuck, but if you include useful ones, its a stamp of legitimacy. It shows you care.
Things like npm version, test status, coverage numbers. It’s nice flair.
Also, Markdown supports raw HTML, so you can make your repo header look nice. Center things, add a quote, jazz it up a bit.
If you really wanna go for the gold, add a contributors entry like here: https://github.com/kentcdodds/all-contributors
It a really nice way to recognize people who have contributed to the project. God that Kent C. Dodds is SUCH A NICE GUY. FUCK.
Release & Marketing
So everything is tight, its time to shine. How can you get people to actually check out and use your new lib?
My recommendation is very specific. Release at 12pm EST on a Monday. It’s the end of Europes day, New York’s lunch break and San Franciscos hour in the morning before anything gets done. You have a large portion of your target audience twiddling their thumbs, fucking around on the internet.
As for how to release, I think Twitter is the first stop. Make extravagant claims.
“Tired of writing CSS with a keyboard? Guess what, now you can do it with an XBox controller!”
“Stack Traces got you in the dumps? HOW ABOUT IF THEY WERE EXPLORABLE IN FUCKIN VR!”
Do you. But have a hook. And use pictures. Or video. Make it immediately clear what this thing does and why they should use it, with a link. The process should go:
- Browsing Twitter
- Oh look at this tweet
- Oh shit! This thing does WHAT!?
- Clicks link
- Lands on repo, oh cool it looks legit af
- Goes to Getting Started
- Copy/Paste into terminal, Rock and Roll
- [clicks star button]
Your mileage may vary depending upon your follower count and their predisposition to whatever tech your selling, but this generally works. Outside of Twitter, great outlets to drop this on are HN (sorry) and Reddit.
Also, if the idea warrants it, accompany your release with a blog post, especially if you’re doing it under the banner of a company. You can show it off in longer form.
Be Bold. Be Confident. Be Ready To Get Your Shit Ripped Apart.
I was dreading getting to this portion, because this is where my experience has traditionally shit the bed. But I’m happy to talk about what I’ve learned through failing in every way imaginable and hopefully getting you read for whats going to happen.
So you released your library. It went one of two ways:
- It flopped.
Who cares. I have this happen all the time. Go back to the drawing board. Sometimes some stuff doesn’t catch fire. It doesn’t mean you suck or your idea sucked, it just wasn’t time. The important thing is that you built something. You built it right. And the next time you build something, you’ll be even better prepared for success. Pat yourself on the back, you fuckin shipped!
2. It got popular.
So here is where you are truly fucked. People like your shit. Its getting tweeted out. You are fixing bugs and fielding questions and defending the idea. I have some opinions.
First, if anyone expresses interest in working on your lib, make them a maintainer. Hold on:
IF ANYONE EXPRESSES INTEREST IN WORKING ON YOUR LIB, MAKE THEM A MAINTAINER
Here’s why: Time will pass, new technologies will emerge, problems change. You change. Your repo will still be there. If you don’t delegate, you WILL have a bad time. You will burn out on maintenance, you’ll resent the project and it will turn into a shit show. Trust me on this, delegate.
Next up, I want to talk about dealing with people.
This is one of the biggest parts of open source, a lot of the time more important than writing the code. People are going to talk shit to you. People are going to be entitled. People are going to shit on your project publicly.
Fuck those people.
I spent a lot of time fighting about things, and I wish I spent that energy elsewhere. Trust me on this, fuck the haters.
However, be vigilant in identifying haters. You see, sometimes people might appear to be haters, when in actuality they are not. Consider this, you are releasing this source to the WORLD. Providing you’re American, and its done in English, it’s important to remember that not everyone speaks English.
Imagine you want to contribute to a repo thats in Russian. But you don’t know Russian. So you Google Translate “Hey is there a time table on when this will be implemented”. Then say Translate returns in Russian, “WHEN WILL THIS BE DONE”. At first glance you might be like, “Hey what the fuck is this guys problem”, only to later find out that tone doesn’t carry over the internet well, and carries less well between translation.
Be wary of that, sometimes people aren’t being dicks, they just don’t speak your language.
Beyond all that, the best I can tell you to do is to have solid CI on your PRs and have filled out issue and PR templates. You are going to get a metric shit ton of issues and PRs on this repo, and if you want any chance any managing them, you’ll want to set some ground rules. I recommend:
- Ask for a reproduction case or a failing test case
- Ask for the conditions where the bug occured
You don’t have the time to figure out some one off bug. Make the users prove to you that the bug exists and make it simple for you to identify, so you can spend your time fixing it.
Also, its probably worth noting somewhere in CONTRIBUTING.md that people should run ideas by you in an issue before working on a PR. The saddest thing in the whole world is when someone works really hard on a PR that will never get accepted.
Speaking of accepting PRs, the last thing I want to leave you with in this section is that you don’t have to do what people are asking for. I have squandered many an API by caving to the users.
Many times, some people just need one thing for one small isolated problem they have, but its of no value to the greater community. Be vigilant about any modifications to your API, because people with weird edge cases will FUCK YOUR API UP. Do whats right for the core lib, not whats right for some dude building a telemetry system for hang gliders.
Oh I lied, one last thing. USE SEMANTIC VERSIONING. PROPERLY.
Pretty please. Or don’t, and everyone will lose their god damn minds. Also, push tags. And write release notes. Detailed release notes. As your library evolves, its important for invested parties to know whats going on.
Be transparent, clear and informative. Don’t deprecate things without grace periods. If people invested in your library and you go ahead and change things and break their apps, they will not be happy campers. Make updates to your lib in a compassionate way.
By now, you have probably realized that not only do I suck at OSS, but I also suck at writing. But people asked, so I delivered. I hope this word vomit helps someone who wants to release their own open source and saves them some time and some aggravation.
There is a lot to this shit, but if you tick all the boxes, you’ll have a better time than I have had historically, and a good chance at success.
With all that said, I have one last recommendation. Don’t do this unless you actually want to. Don’t feel like you have to. You can get a job without it. You can be a good developer without it. I’ve benefitted from it greatly, and enjoyed doing it, but I will never get the time back that I spent fucking around on libraries for free, that I could have spent with my family or pursuing hobbies or doing literally anything that would provide passive income. Do it because you want to. If you aren’t passionate about what you’re building, it probably won’t succeed.