This post was originally published to Medium on Oct 17, 2022 and the stats listed below have been updated for this post
For the first time since I started my career in web development, I can say I’ve made a successful piece of open-source software, because today my TypeScript package chakra-react-select just passed 1 million total downloads.
What is Chakra React Select? It’s just your standard dropdown select component made for React applications, styled to match the UI component library Chakra UI. However, it’s not entirely my own creation. Instead it’s a wrapper for the majorly popular React Select, which, for a long time, was the most starred React project on GitHub.
Here are some stats showing how far the package has come:
It is currently being downloaded 51,561 times per week and rising
This project all came about in April 2021, when I started searching for a multi select component I could use with Chakra UI that didn’t completely diverge from it’s design system. I wanted a searchable dropdown that allowed me to select multiple states, or something along those lines. I quickly realized I was not alone in this search as I found many many issues on their GitHub repo requesting a component for this purpose.
There were a few custom components people had made for this purpose, but none of them fit for my specific use case.
A few people mentioned that one possibility would be for the creators of Chakra to simply wrap React Select, as it is already a mature package that is highly customizable. However, it didn’t seem like they were going to take that route, and there didn’t seem to be any timeline for them implementing their own. So I figured I’d give it a shot.
I started off with the basics and just customized the styles of React Select using their great styling system until it didn’t look out of place. I was pretty happy with the result so I figured I’d share my creation with the Chakra community as a simple GitHub Gist with a CodeSandbox demo to go along with it. I quickly began getting positive responses and a decent level of interaction on the gist. Since then it has received 30 stars and been forked 10 times. On top of that, the demo has been viewed 37,800+ times and been forked 433 times.
All of the interaction it received motivated me to make it better, so, over time, I made quite a few changes to the gist in an attempt to improve it. However, I soon realized that making edits to a gist is not a great way to push out updates. I figured that, for the most part, only people who were seeing it for the first time would actually see those changes and once they copied the code into their projects, most would probably not look at it again.
So finally, 27 revisions on the gist later, I decided to make it into an NPM package. Going into it, there were some big challenges I knew I would face. The most obvious being that one of the big draws of Chakra UI is that it’s written entirely in TypeScript, a language I had never used before. I knew that if I wanted to make the package as useful as I could, then it would have to be written in TypeScript so users would have the best developer experience possible. The other big issue, and one of the main reasons I didn’t make it into a package sooner, was that I knew there would be difficulties in allowing people to customize the component.
Despite these glaring issues I gave it a shot anyway. And on Sep 13, 2021 I made my first commit to the new repo and published the first version to NPM. I started off very basic. I just wanted it to work in the same way my gist did- with no TypeScript in sight. And, having barely made any NPM packages, this took a bit of figuring out. I ended up publishing 10 versions that day, none of which worked, so I decided to put it down for a bit and come back to it later.
After a week (and some prompting), I decided to give it another shot. Once I changed the build tool I was using from microbundle to rollup (and published another 10 versions), I had a working package I was satisfied with. I shared it on a few of the relevant issues on the Chakra UI repo but quickly realized that the next step would be converting the whole thing to TypeScript.
Luckily for me, I wasn’t starting from scratch. A large portion of the comments on the original gist were about adding TypeScript support and a couple people lent a hand. These versions helped tremendously in getting started considering I had no TypeScript experience. I published the first (semi) functional TS version three days later, but it wasn’t until a few months later that the types actually worked properly.
Soon after that someone made the first issue on the repo. As I had anticipated, it was asking about how to customize the styles further than I already had. three people commented on the issue requesting the same thing shortly after that, so I knew I had to figure something out. However, the solution definitely did not come quickly.
It wasn’t until three months later (Jan 2021) that I finally figured out a good solution. In order to make it customizable in a unified way, I had to make a replacement for every sub-component that makes up React Select so they could be styled as Chakra components. On top of that, I had to make an entirely new styling system in parallel to React Select’s own. The process required me to add a ton of new code to the package but by the end of it I was very satisfied with how it worked. On Jan 4, 2022 I released email@example.com and finally put all the customization requests to rest.
The next problem to tackle was fixing the TypeScript integration. I hadn’t realized it, but for the entire time up until this point, none of the prop types on the component were being enforced properly. On top of that, it was brought to my attention that firstname.lastname@example.org, which included built in TypeScript support was released one day before I released my original TS compatible version that was made to work specifically with react-select@4. Perfect timing right?
Less than a week after releasing v2 I had a chance to sit down and really dig into how the types worked for React Select v5. Finally I had a breakthrough, and with some major structural changes I had a version that was fully TypeScript compatible. These changes were released in v3.0.0 on Jan 10, 2022, and I was finally confident that the whole package was production ready for Vanilla JS and TypeScript applications.
It seems that the users agreed it was production ready at that point because from there on the downloads/week then steadily rose up to the point it’s at today. I also noticed a major change in the types of issues that were being filed on the repo. All of a sudden they went from “why can’t I do X with this package” and “none of the types are working” to simple questions about how to actually use it. There were still some bugs to work through after the release of v3 of course, but they were more about polishing it up than major app breaking issues. For the most part since then, I’ve added a few new features (some contributed by others), fleshed out the documentation, and answered questions as people have had them.
Overall, making this package has been a great experience. I’ve learned a ton about different build tools, how TypeScript works (which I now use in all of my production applications), and how to support an open-source community. I’ve also learned about the struggles open-source maintainers deal with when supporting a project, such as receiving the same question multiple times or being forced to tell people that their feature request can’t be added. But even taking the struggles into account, I’m happy I started this project and I’m very proud of how far it’s come!
There’s a few pieces of advice I would give anyone trying to break into the open-source space;
Find a gap, somewhere there is a clear need for something, and fill it. I’ve made things in the past that have been unique enough to not have many alternatives, but there wasn’t a clear need for them in the first place. In this case I only made this package because I needed it for myself and just so happened to have a community looking for something similar. Because of that, I was able to get my package out there simply by linking to it in those places where people were asking for it.
When you’re just starting off, try and answer all questions, no matter how dumb they might seem. As the person who made the software some questions may seem trivial or obvious to you but they might not be as clearly described in your documentation as you think. An added benefit of this is that the more issues/discussions you answer, the more content people will have to look through before asking questions in the future.
Adding to number 2- if you find yourself getting the same question over and over, try and highlight those things more in your documentation. Good documentation will save you time explaining things down the road, and your users will help you understand what they need for the documentation to be more clear and complete.
You don’t need to host an entire website for your documentation, especially if your project isn’t that big. The README on your GitHub repo can be plenty, and sometimes its easier to find what you’re looking for with a good old ctrl/cmd + f. However, including complete functional examples certainly helps. In the case of React components, I recommend linking to CodeSandbox examples so people can see different use cases in action and tinker with the implementation themselves.
At the end of the day, just start making things! You never know what might take off unless you put your code out there and you can’t put your code out there if you don’t code things in the first place.