In this episode, Oh My Zsh founder Robby Russell tells the story of how he unexpectedly launched one of the most popular zsh configuration frameworks out there. He shares his process, some mean tweets, and his advice for people starting open source projects.
Written and read by Robby Russell: https://twitter.com/robbyrussell\xa0
Original article:\xa0https://fcc.im/2HzyjYN
Learn to code for free at:\xa0https://www.freecodecamp.org
Intro music by Vangough:\xa0https://fcc.im/2APOG02
Transcript:
How I unexpectedly built a monster of an open source project
It was the summer of 2009. I found myself helping a coworker debug something in their terminal. As I attempted to type in a few command lines, I noticed that the prompt wasn\u2019t responding to the shortcuts that my brain had grown accustomed to. Frustrated, I exclaimed, \u201cwhen are you finally going to switch over to Zsh?!\u201d
(yeah, I was the type of annoying coworker that would constantly point out that X was better than Y when given the chance. In hindsight, I don\u2019t know how they put up with me\u2026but between you and me, I had a point.)
At that point in time, I had been a daily Zsh user for a little over three years.
Some of my #caboose friends shared a few of their .zshrc configurations within our IRC channel. After a few years, my .zshrc file grew into a tangled rat's nest. Honestly, I didn\u2019t know what ~30% of the configuration did. I trusted my friends enough to run with it, though. What I did know was that I had some git branch and status details, color highlighting for a few tools (i.e., grep), autocompleting file paths over SSH connections, and a handful of shortcuts for Rake and Capistrano. Working on a machine with a default Bash profile felt remarkably archaic; I\u2019d become dependent on these shortcuts.
A few coworkers were happy to copy/paste the .zshrc file that I shared and begin using it. A few others wouldn\u2019t because they knew that I didn\u2019t know what some of it did. Fair enough.
After a few attempts to convert them and getting nowhere, I opted for a different approach.
First, I reorganized my .zshrc configuration, which involved breaking it up into a collection of smaller files. My thinking here was that this would a) help me better understand how all of these bits worked while b) helping educate my peers when they went to read the code.
Pre-empting their next question, \u201chow do I get this to work on my machine?\u201d, I drafted the first setup instructions.
Most importantly, I packaged all these files into a shiny new git repository. I figured that if I tossed it up on Github, my peers would be able to collaborate with me on improving it.
While not a huge leap, it was a step above inviting people to copy/paste a text file from Pastie.
On Aug. 28th, 2009, Oh My Zsh was born.
\u2026but, wait a minute!! Where are the themes? Where are the plugins? Installation scripts? Logo?
This might come to a surprise to most of the Oh My Zsh user base, but none of those were features that I had considered. My goal with the project was not to build a framework for maintaining Zsh configurations but to share my own config with my coworkers so that they\u2019d use Zsh.
Within a day of sharing it with all of my coworkers, everyone at Planet Argon had migrated from Bash to Zsh.
Victory! \u2026or so I thought.
The first feature request came in the next day.
\u201cHow do I customize MY prompt?\u201d
Two coworkers asked me how they could customize their prompt. They wanted to change the colors and the information that was displayed.
What the hell!? Wasn\u2019t my prompt compelling enough for them? So nitpicky. ;-)
I pointed to the prompt.zsh file and said they could modify that.
Quickly, this became an issue as they now had their own version of that file. As a result, this would add some complexity if we all wanted to share some of our shortcuts and features as we\u2019d have conflicts to deal with.
Hmm\u2026
So, a day after first announcing Oh My Zsh on my blog, I began introducing the initial concept of themes.
Meanwhile, I got my first external pull-request from Geoff Garside to add a few aliases for TextMate. (Notice how that went straight into a catch-all aliases.zsh file)
A day later, another theme was sent over. Groovy, I better add a link on the README to see some screenshots on the wiki.
Within a month, we had a dozen themes contributed to the project.
This began to be a really popular aspect to Oh My Zsh and we had to start hitting the brakes on accepting themes once we passed 100. (we\u2019re currently at ~140 and rarely accept new ones)
Simplifying setup with an installer
It occurred to me that the initial setup was requiring people to run a handful of commands. Rather than asking people to re-type and/or copy/paste a handful of commands, I felt that it would be more efficient for both parties (as it\u2019d reduce the questions my coworkers would have when they hit a problem and/or skipped a step).
An installer was born.
My initial thoughts were to handle save folks a few steps by automating the installer. If everyone ran the same commands, then we could cut down on human error (skipping a command, typos, etc.). I also wanted to be mindful that people might be switching from either Bash or an existing cobbled-together Zsh configuration. To help them with a possible switch back to the previous shell, we made a backup of their original configuration file. Finally, we\u2019d switch their default shell to Zsh.
\u201cHooray! Oh My Zsh has been installed.\u201d
Oh, right. How will people be able to stay updated with the new changes to the project?
The next day, I added an upgrade script that strolls over to the Oh My Zsh directory, fetch updates from the git repository, and returns you to your previous working directory.
Far from rocket science.
About three weeks later, it became obvious that my coworkers weren\u2019t manually keeping up with all of the new updates to the project. Rather than reminding them to do that from time-to-time, I added functionality that would periodically prompt the user to check for updates.
Up until this point, this felt like the most complicated piece of code in the project. I wish that I could remember who gave me the great idea to use an epoch value here.
In my opinion, it was also the turning point for the project.
While a handful of people were using it, this functionality would allow nearly every user to stay up-to-date on project changes and more importantly, stay engaged. When they would run the updater, they\u2019d see a list of files changed and that would, subtly, introduce them to new features\u2026 a la, \u201cI wonder what that theme looks like..\u201d
Sadly, not everyone has been a fan.
Despite a few vocal opponents over the years, I\u2019ve stood by my decision to keep this as a default setting.
Back in 2012, we made a change to reduce the frequency of auto-update prompts by 50%.
The auto-update has allowed us to ship new features, performance improvements, and bug fixes without relying on everyone manually doing it. I\u2019m convinced that this feature has helped keep the community engaged.
This Muffin Needs Candy
While the project was attracting a lot of themes, I really felt like the project could benefit from branding.
My solution? Ascii art.
I have no idea what prompted the git commit message.
My thought process here was\u2026 sure, you get a bunch of useful shortcuts and themes when you begin using Oh My Zsh, but I really felt like the first impression after the installer would run was an opportunity to delight new users.
People have been asking me to print shirts with the ascii art for quite some time. (we\u2019ll likely do that this summer\u200a\u2014\u200afollow us on twitter)
Plugins
Ten months after open sourcing the project, users had begun to request the ability to not have everything get loaded up. For example, a Python developer might not need the Rake and Capistrano related aliases to get loaded like a Ruby developer would.
So, we implemented a basic plugin system that would allow folks to decide which to load on initialization by changing a value in .zshrc.
When this feature was released, there were five plugins bundled.
Within a few months, I started to get pull requests for new plugin ideas.
Within a year, I had accepted over 40 plugins.
Within two years? Over 70 plugins.
Currently, we have plugins for adb, ant, apache2-macports, archlinux, autoenv, autojump, autopep8, aws, battery, bbedit, bgnotify, boot2docker, bower, branch, brew, brew-cask, bundler, bwana, cabal, cake, cakephp3, capistrano, cask, catimg, celery, chruby, chucknorris, cloudapp, codeclimate, coffee, colemak, colored-man-pages, colorize, command-not-found, common-aliases, compleat, composer, copydir, copyfile, cp, cpanm, debian, dircycle, dirhistory, dirpersist, django, dnf, docker, docker-compose, emacs, ember-cli, emoji, emoji-clock, emotty, encode64, extract, fabric, fancy-ctrl-z, fasd, fastfile, fbterm, fedora, forklift, frontend-search, gas, gem, git, git-extras, git-flow, git-flow-avh, git-hubflow, git-prompt, git-remote-branch, gitfast, github, gitignore, glassfish, gnu-utils, go, golang, gpg-agent, gradle, grails, grunt, gulp, heroku, history, history-substring-search, httpie, iwhois, jake-node, jhbuild, jira, jruby, jsontools, jump, kate, kitchen, knife, knife_ssh, laravel, laravel4, laravel5, last-working-dir, lein, lighthouse, lol, macports, man, marked2, mercurial, meteor, mix, mix-fast, mosh, mvn, mysql-macports, n98-magerun, nanoc, nmap, node, npm, nvm, nyan, osx, pass, paver, pep8, per-directory-history, perl, phing, pip, pj, pod, postgres, pow, powder, powify, profiles, pyenv, pylint, python, rails, rake, rake-fast, rand-quote, rbenv, rbfu, rebar, redis-cli, repo, rsync, ruby, rvm, safe-paste, sbt, scala, scd, screen, scw, sfffe, singlechar, spring, sprunge, ssh-agent, stack, sublime, sudo, supervisor, suse, svn, svn-fast-info, symfony, symfony2, systemadmin, systemd, taskwarrior, terminalapp, terminitor, terraform, textastic, textmate, thefuck, themes, thor, tmux, tmux-cssh, tmuxinator, torrent, tugboat, ubuntu, urltools, vagrant, vault, vi-mode, vim-interaction, virtualenv, virtualenvwrapper, vundle, wakeonlan, wd, web-search, wp-cli, xcode, yii, yii2, yum, z, zeus, zsh-navigation-tools, zsh_reload.
In total\u2026 214 plugins. Admittedly, not everyone has been impressed by this.
I do agree that could be drastically improved.
The few times that I considered it, I found the proposed approaches to be too complicated for folks who aren\u2019t yet familiar and/or comfortable with the terminal. Perhaps a more sophisticated approach for version 2 of the framework. (more on this later)
There has, also, been a part of me that has felt like this project would only be of interest to people for a few years. As users gained more experience and/or as technology evolved, the framework would be left behind by shiny new projects that solved problems far better than we had.
I never thought Oh My Zsh would still be building momentum nearly seven years later.
Where do all these new users keep coming from? I \u2764 you people!
While I have many stories to share (and intend to write more on this topic), I wanted to speak to those who have been debating the idea of open sourcing a project.
Eight Considerations For Your Open Source Project
Don\u2019t start with a wildly ambitious goal. Start your project with a simple, attainable goal. What does success look like? In my scenario, I wanted 1\u20132 people on my team to use my scripts. The project was a success in under 24 hours.
Everything since has been extra-credit.
Don\u2019t try to account for every scenario. If I had gotten hung up on some long-term details for the project, Oh My Zsh would never have happened. Nearly everything that has been added to the project has come organically post-initial release.
One of the beautiful aspects of an open source project is that your user base can help shape it.
Don\u2019t try to make it perfect. Worrying how other people are going to react about your code shouldn\u2019t be your biggest concern. Does it work? How do they feel when they\u2019re interacting with it should be a higher concern. In my case, I\u2019ve had some great contributors over the years who have helped tidy up and improve the quality of the code that I originally released.
Rarely has anyone said anything critical about my old code\u200a\u2014\u200amaybe they should have, though. ;-)
Don\u2019t try to be everything to everyone. There have been a few points in the history of the project where we hit a crossroads. In particular, there was a time when a huge rebuild was proposed, which I was quite excited about until I was able to wrap my head around some of the changes.
As a result, a fork was rebranded and we agreed to follow different paths. Not everyone was happy with my decision here, but it was during this period that it became clear (to me) that I wanted to focus my attention on folks who weren\u2019t too comfortable with the terminal and/or git.
Don\u2019t stop thanking contributors. If anybody helps your project out, please let them know how much you appreciate their effort. I can\u2019t thank my contributors enough. One of my biggest self-critiques related to this project is that I\u2019ve not been consistent enough in being vocal about my appreciation.
There are 910 people from all over the world who have their code accepted into the master branch of Oh My Zsh at the time of writing this.
It\u2019s such a long list that Github can\u2019t even list them all.
In particular, thank you. (you know who you are)
Don\u2019t forget the documentation. Over the years, documentation of plugins and functionality has been vital to helping inform users on how to take advantage of the framework.
I wish we had adopted this convention several years before.
The README file is going to be seen the most\u2026so make it count. In my case, I opted to introduce people to my personality and dry sense of humor.
Honestly, seeing tweets like this means the world to me.
Don\u2019t forget about the rest of your life. Again, I never anticipated the project turning into what it is today.
Are you familiar with the anecdote about the frog in a pot of boiling water?
It took me 3\u20134 years, too many, to finally bring in another person to help maintain the project. I kept thinking that I could catch up with all the open pull requests and issues. What I kept telling myself was that folks who know how to fork the project can make their desired changes and work off of that, so reviewing and approving pull requests is a nice-to-happen versus a need-to-happen.
In practice, it\u2019s somewhere in between. I do feel a bit bad for old pull requests lingering, but I also don\u2019t keep Oh My Zsh as one of the top few projects on my plate.
Outside of Oh My Zsh, I run a 19-person agency, play guitar in an instrumental post-rock band, sit on the board of directors of a local homeless shelter non-profit, travel with my camera a lot, ride my motorcycle, ride my bicycle, and try to keep a social life with my friends. Oh My Zsh fits somewhere in amongst all of these.
It\u2019s not at the top of my priority list. It\u2019s not at the bottom. It\u2019s somewhere between. This isn\u2019t an excuse to not being able to keep up with the community, but more of a reminder that those other things should matter to you, too, if you\u2019re about to start your own project.
(I will write more on the topic of leading an open source project w/maintainers in another story\u2026 \u2764 are you following me? \u2764)
Don\u2019t forget to have some fun. When you start your project, decide if this is going to be serious work time or play time. Perhaps it can be somewhere in the middle.
Oh My Zsh has, always, been a play time activity project for me.
Knowing that one of my playful projects has been and continues to be enjoyed by people is such a wonderful feeling.
Some might call it a passion project. I call it playtime.
Interested in my fun open source project?
You can learn more at http://ohmyz.sh.