TL;DR

If you plan on releasing a library as open source, please make sure it has

  • Clear dependency/installation instructions
  • At least one brief documentation guide
  • A change log and tags in the repo
  • Some information about supported language/runtime/tool versions and project maturity
  • A mailing list where users can ask questions and help each other

Doing anything less than this will cause some of your users grief and anger. And likely some wasted time.

How To Make Your Open Source Library Really Awesome

Year after year, more and more people release libraries they’ve developed and would like to open source. Today we’d like to share a little bit of our experience about how to make sure users of your library are content with it.

There is one Rule of Thumb to this:

Don’t make your users mad

also known as

Don’t make your users want to break the computer

now lets see how specifically we can achieve that goal with a reasonable amount of effort.

Give It a Really Useful README

Even if your project has a nice site, it is likely that the first point of contact of potential users with it will be by reading the README file. We need to make sure it is awesome and contains useful information.

Provide Dependency Information

So you release open source software. This probably means you are kinda smart. Good for you. Unfortunately, not everybody is and some people are completely new to the language/ecosystem your project is in. This means that what is obvious to you is not at all obvious to many other people.

One such thing is missing dependency/installation information.

How do I even install this, was it so hard to make this clear?

is something that quickly leads to anger. Digging in the source to find our your artifact/gem/package name is annoying and some projects use really creative (read: stupid) names for artifacts that do not match code repository name, etc.

Relieve your users from having to deal with this crap. Make it dead obvious how to add a dependency on your project, ideally by copy-pasting a snippet.

See Welle if you need an example.

State Project Maturity Clearly

Have you been using it in production for months? Is it something you still believe is incomplete? Do you expect the API change drastically in the next version? Is this project mature and safe to use even for the most demanding and conservative projects?

State all that clearly. And next time you won’t waste a week of your time because you’ve made the wrong call on a library that did not provide any maturity information, you will realize how much difference a few sentences can make to real people.

Document Supported Runtime/Language/Tool Versions

Clojure has a very good track record when it comes to backwards compatibility. It is almost too good to be true. Besides the 1.2 to 1.3 migration, subsequent releases are pretty much a drop-in replacement for the vast majority of projects out there. As such, projects that have moved beyond 1.2 are generally on the most recent stable release

However, this won’t always be the case. At some point, a future Clojure release will have to break compatibility. How do we not make our users furious? By clearly stating what versions are supported in the README.

All it takes is writing one line of text. One less tweet on the week of your release and you save beginners potentially a lot of head scratching.

If you need an example, here’s one from Welle.

State What License You Use

You may not care about licenses much, but people who want to use your library at a BigBucks Inc do. They must know. And it may be a deal breaker for them when they want to adopt Clojure/Node.js/Scala/Go/whatever.

So state your license clearly. And please, use something business-friendly unless you have good reasons. Apache Public License 2.0 and Eclipse Public License are good, friendly choices. Note that some licenses (e.g. MIT) are friendly and popular but do not offer any patent protection, which should not be ignored in the current legal climate.

Finally, remember that you can double-license, e.g. APL2/GPLv2 if you really want to be license-neutral. Then your users will pick what suits them.

When in doubt, refer to TL;DR Legal, open source licenses summarized & explained in plain English (but don’t consider it to be legal advice).

How To Fuck It Up

If you want to completely screw your users, do this:

  • Put a nearly blank README to your project’s root
  • Make it say “patches welcome” at the end
  • Invent your own license or use a completely unfamiliar one, such as WTFPL

Then your project will never have any users. Guaranteed.

Document Your Project

Documenting things is not easy and can be time consuming. However, documentation is the single best thing you can do to your users. Not only it saves them a lot of time, it makes them confident that your library is not abandonware.

Documentation helps your users accomplish things they decided to use your library in the first place. In the words of Rob Pike, it “empowers them”. It shows them that you care. It shows them that you are a real person, not a robot spitting code.

After about 2 years of working on ClojureWerkz, I can confidently say that there is nothing our users are more thankful for than documentation for our projects:

Writing great documentation takes time. Fortunately, modern tooling also helps you quite a bit and reduces the annoyances you have to deal with by a lot.

For ClojureWerkz projects, we’ve open sourced our Jekyll-based documentation site template. We are not great at CSS and the visual aspect of design, so we use Twitter Bootstrap. While our doc sites could look better, it is certainly pretty good compared to most open source projects out there. And you can use our template or create a similar one for your projects.

Better yet, if you open source your documentation site (and there is no reason to not do so), you will likely see people contributing minor improvements and corrections earlier than they will contribute code changes.

If you are still not sure whether documenting your project is worth it, watch this talk by Jacob Kaplan-Moss:

</embed>

How To Fuck It Up

If you want to completely screw your users, do this:

  • Don’t write a single documentation guide, not even one example
  • Make sure your API reference is outdated by at least 3 months
  • Claim that people who are not willing to read the code to figure out even the most basic things are stupid and should flip burgers instead

Make It Easy to Upgrade

At some point, you are going to make another release of your project. This is another opportunity to either make your users happy that they’ve gone with your library or make them furious and waste their time.

Give a Fuck About Backwards Compatibility

One of the most infuriating things about software development is that moment when you upgrade a library and hundreds of tests fail. The only thing that angers me more is when I also have to rewrite half of my codebase because someone somewhere decided that breaking the public API without warning is fine.

So, commit to maintaining backwards compatibility. Of course, you don’t have to support projects from 15 years ago like OpenJDK does. But deprecate things before removing them and make it easy to discover what has changed.

How do you do that? By keeping a change log.

Have a Change Log

Every once in a while, your users will upgrade (more on this later in this post). The main questions they are going to ask themselves is

What has changed in this release?

and then

Will my code break? Will I have to rewrite it?

and finally,

Will Joe the ops guy hate me for upgrading?

All of these can be answered by having a change log. It’s like Twitter except it’s actually useful. Here’s how it works:

  • Every time you fix a bug, you write a brief entry to the change log
  • Every time you add a feature, you briefly mention it in the change log with a few code examples
  • Every time you make a breaking API change, you clearly state that in bold in the change log

That’s it. There is no step 4.

Change logs typically use reverse chronological order. Changes are grouped by versions. If you have multiple branches (e.g. master and 1.0.x), each one has a separate change log.

That is all. For example, here’s Welle’s change log.

Tag Releases

It’s that time again. You’ve bumped the version and about to publish artifacts. Stop and make another thing first: tag the commit that changes the version. Without tags it will be a royal pain to come up with a diff betwee nversions.

Some dependency (e.g. Bundler, Rebar) and configuration management tools can use tags and developers will expect tags to be available.

Use a consistent version scheme, e.g. v1.0.0-alpha1, v1.0.0, v1.1.2, etc. Having inconsistent tag names will guaratee ops people will hate your project till the end of days.

Announce Releases

Next thing to do after you push a release out is to write a blog post or simply a post to the mailing list of your project or a larger relevant mailing list (e.g. Clojure mailing list or RabbitMQ Discuss).

Make sure the subject starts with ANN or [ANN] to indicate that it is an announcement, e.g.

ANN Welle 1.5.0 is released

In your announcement make it clear what the project does and if the release is backwards-compatible or not, and link to the change log where users can find more details. That’s it.

Use Preview/Snapshot Versions For Development

Ever saw a project that has the same version, e.g. 0.2.1, for half a year? How do you know which version is actually 0.2.1? Is it a version in development? Did someone forget to bump it after a release? What’s going on?

This is driving all developers crazy. Don’t be that person. Use preview/snapshot versions for development and only “seal” versions when you are about to tag and cut a release. Then immediately bump the version to development.

Examples of development versions:

  • 1.1.0.pre1
  • 1.1.0-alpha1
  • 1.1.0-SNAPSHOT (for JVM languages)

Any other development version naming scheme is confusing and will guarantee your users a bad time.

How To Fuck It Up

If you want to completely screw your users, do this:

  • Break your public API randomly, ideally in subtle ways that your test suite won’t even reveal
  • Forget to bump development version
  • Never tag releases
  • Never announce releases

Use GitHub

I have no affiliation with GitHub and don’t assume Git is “the best” version control system out there. But it’s pretty good. And nearly everybody is on GitHub these days.

GitHub makes several things easy:

  • Discover your project
  • Browse and search code
  • Bring your attention to issues by filing issues or @mentioning you
  • Contribute trivial changes

Maybe the most importantly, GitHub is pretty friendly to less technical people. Yes, it is, and they are working hard on making it even better.

Using GitHub means you’ll have an extremely easy to use CI service: Travis CI.

You will get a lot more admiration from your users if you won’t make their life harder by asking them to deal with patches, look for your email across the Web to report issues and clone your 300 MB repository over poor 3G just to edit one typo.

Don’t be difficult.

Have a Place Where Users Can Get Support

If your project reaches any reasonable kind of popularity, you will have to answer questions about it. For that, set up a mailing list (a Google group will do) and if you frequent on IRC, start a channel.

Think you don’t have any time? The best part about having a mailing list is that users will quickly start helping themselves if you give them a way. So clearly indicate ways to get support in your project’s README.

Search Twitter for the name of your project every so often. You will discover all kinds of questions, criticism and praises. If you use Twitter actively, start a separate account for your project, like we have done with @ClojureWerkz.

It will help you build a community, learn about how people use your project and what can be improved. Finally, it will help you find people who will be able to help maintain your project. Not only it will save you time, it will encourage those people to spread the word about it.

If you need an example, Welle README has a section about community and support.

How To Fuck It Up

If you want to completely screw your users, do this:

  • Be hip and disable issues on your GitHub repository
  • Use a contributor agreement users have to mail in paper to Tanzania
  • Insist on using patches even for one line changes to the README
  • Put your repo into Darcs even if it’s a Ruby or JavaScript or Clojure project
  • Make it hard to find where the repository is

This will prevents others from contributing to your project and stealing some of the credit from you.

Pass It Over

At some point you may become disinterested in maintaining your project. Maybe you’ve moved on to a new job or no longer use your own project. Announce it on the mailing list, ask someone to take over your project. Sooner or later, someone will help. Being on GitHub helps with this, especially after they’ve introducted a feature that lets you transfer repository ownership.

No matter what you do, don’t turn your project into abandonware. This is the most sure way to want your current and future users to go on a kitten killing spree.

It’s always better to pass the project on than to make excuses later.

How To Fuck It Up

If you want to completely screw your users, do this:

  • Simply stop contributing to your project and answering mailing list questions without any explanation
  • Ignore pull requests, claim they should be called something else and are not really useful
  • Claim you simply are a Get Shit Done guy who loses interest once the problem is done

This will make sure your project will eventually be forked at least 300 times and an alternative will be created because figuring out which fork has what bugs fixed will be too annoying.

Final Thoughts

As you can see, it is not that hard to make your project approachable. Besides documentation guides, it does not take much to make sure your users are not mad and ops people don’t hate you.

Maintaining open source projects takes time and effort. But it pays off. I’ve been on GitHub since beta and can say that few other things have brought me more professional opportunities I’m blessed to have today than being active in the open source community.

And if you are not going to make something awesome, maybe do not release it in the first place.

Michael.