Today we’re going to compare promise libraries, this isn’t about finding the best library as such a thing does not exist, all of the libraries make different trade offs to try to be good for certain things.

So disclosure: I’m going to try to be as unbiased as possible but I did write one of them (lie) so if nothing else, that library is going to be optimized for the same trade offs I find important.

There are a lot of spec compliant promise implementations, my criteria for picking these are

I must have heard of it. It must be used in the wild. It must have ~ES6 syntax (take a resolver function to create a promise at the minimum). Provide microtasks in a reasonable manner (aka avoid setTimeout in modern browsers). Be aplus spec compliant.

The libraries I chose were

And these broadly fall into 2 categories:

bluebird, Q, and when are tool kits that in addition to providing promises also provide a plethora of helper functions for dealing with promises in the footsteps of the venerable async library.

lie, RSVP and then/promise are basic promise libraries which stick close to what the ES6 promise object provides, namely they have static resolve, reject, and all methods and their prototype has .then and .catch methods.

I had a bunch of comparisons I was going to do but then I found a nasty bug in Lie and spent a bunch of time on that so I’ll just cut the my findings.

My benchmark results are here If you want to do the benchmarks yourself just download the bluebird repo and run them there, the size comparisons are here.

Bluebird

Bluebird is the fastest by far, through the speed should be taken with a grain of salt as the bench marking tests were written by the guy who wrote bluebird written by somebody else originally but the live in the bluebird repo, that being said they are the best promise speed tests (as opposed to latency) that I can find so that’s what we got.

Bluebird is approximately equal in size to the other 5 libraries combined (15k minified and gzipped) , so my recommendation would be to without a doubt use it in Node and if you don’t have to be hyper concerned about download size use it on your client size App. Client size libraries are where I tend to be most concerned about size and I would avoid using bluebird there, if your library works in node and the browser you can use browserify to set up an automatic substitution that replaces bluebird with something smaller on the client side while using it in node, it’s what I do in a couple libraries.

When

When was pretty consistently the second fastest of the libraries but at less then a third of the size of bluebird when is by far the best choice for promise tool belts in size contentious situations (i.e. client side libraries). Plus a couple of the guys who write it are Boston based like me so extra credit.

Q

Q is an order of magnitude slower then all the other libraries. I really can’t recommend using it in production, which is sad because it is the most popular of all of these (I’ve seen articles using Q and promises interchangeably). Q is the only one of these libraries to that does not implement version 1.1 of the A+ promise spec, implementing the 1.0 version. The 1.1 test suite is deviously thorough and the lack of conformity at the moment is another reason to avoid Q.

RSVP

RSVP is a bit of a strange case, unlike the previous 3 libraries the only extra method it has is a ‘hash’ method which is like all but for objects, (edit: as pointed out on twitter, it also has finally) but at the same time it’s more similar in size to Q and When (~4k minified and gzipped) and has some other features like uncaught promise catching and long stack traces that tend to be in the tool kit libraries, its performance is a a bit strange in that it is very bad in version 0.10.28 of node but in 0.11.13 it (and then-promise) are both significantly faster making me suspect some new optimization in v8 that is helping it. Though even in 0.11.13 it’s performance isn’t that good and if I was picking a 4k library I’d go for when which is faster and has more features. That being said it’s bundled with ember so if you’re in an ember app or something else that already includes it it’s a fine choice (and now works in web workers)

Then-Promise

This library is the first of smaller ones aiming to be drop in replacements for ES6 spec promises in order to make it easy for libraries to return promises. That being said it does offer a few nonstandard methods. Size and performance wise it’s pretty similar to Lie so while I’d recommend my own library this is an equally good choice.

Lie

My promise library which like then-promise is a minimal one, it’s performance is now the same as then-promise but when doing this article I had to fix a performance killing bug (which will probably be the subject of another blog post). Overall it’s size is pretty similar to then-promise (200 bytes larger then then-promise when gzipped and minified), its performance is similar (faster in certain situations slower in others) and while it doesn’t offer any helper functions it does use low latency async techniques on a wider set of platforms via immediate.

Honestly I use this one for my stuff and we use it on pouchdb for the browser but you’d do well with either this or then-promise.

Edit: see my next post, I ended up making lie considerably faster and can now say that it is faster then then-promise and you should use it.

Wrap up

I’m somewhat concerned about how badly Q did, if there is an issue with the benchmarks I would be more then happy to rerun them after a fix goes through. Also in the interest of fairness as I did wait until after I fixed a bug in my own library if any of the other libraries put through speed improvements I can rerun these tests.