This post reflects my opinions about immutability in Moment.js. I do not speak for our entire team.
About five months ago now, I joined the maintainers team of Moment.js. I actually didn’t have much OSS experience before joining the Moment team, so jumping into such a massively popular library has been quite the experience. I have learned a ton about JavaScript, dates, and even how standards bodies work. What I have learned the most about though, is what it means to be an OSS maintainer.
The first thing that I will tell you about any OSS maintainer is that we all want to make you, the user, happy. While we’re admittedly getting some benefit from a ‘personal brand’ standpoint, none of us on the Moment team have ever made a single dollar off of the library directly. We do it for the love of code, and for the love of our users.
Sometimes though, we end up in a position where we can’t deliver to our users in the way that we want to. One such example is changing Moment to have an immutable API.
This issue about making Moment an immutable library has been open since 2014, and in fact discussions of immutability of the library date back to 2012. There are hundreds of comments on the issue, and it gets a +1 type comment or thumbs up at least once a week. With the increase in popularity of React.js, the interest in this issue is going steadily up. We have a couple other big issues that also get +1’d a lot, but the interesting thing about immutability is that the people giving feedback on this issue are PASSIONATE about it. This is not a ‘nice to have’ for them. They believe it is an essential feature of the library that is missing.
Now, it is important to know that all of Moment’s maintainers agree that date and time types should be immutable. If we were sitting down and writing a new date and time library today, that is how we would make it. However, changing Moment to be an immutable API has some very big logistical concerns for us.
In fact, changing Moment from mutable to immutable is almost like making a different library. If this change is done ‘in full’ and not as an add-on, it potentially creates a breaking change for practically every line of code that uses Moment.
But what does that really mean?
Moment.js has been around for five years, which is an eternity in the world of JavaScript libraries, and it isn’t really slowing down in usage. A quick analysis of some stats:
- 4.5 million NPM downloads a month
- 15,000 visits a day to Momentjs.com
- Average of 75 stack overflow questions a month in the last year
- 40 GitHub Issues for June 2016 (so far)
- 21 Pull Requests for June 2016 (so far)
These stats are just for Moment.js core. Moment TimeZone and the docs add many more issues and pull requests.
We have no way of knowing how many people are using Moment. We can know the NPM download number, but I would be surprised if that represents more than half of our user base. Other package managers, CDNs, etc are adding many more.
What we do know is that because of those numbers our workload currently looks like this:
Iskren – Moment.js releases, pull request reviews, major code changes
Tim – All Moment TimeZone code and releases
Isaac – GitHub issue management, pull request reviews
Matt – Moment TimeZone GitHub issue management, Stack Overflow questions
Maggie – Documentation maintenance, Stack Overflow questions
All of us do a little bit of every category you see there, but this is generally how everything shakes out. The critical thing to notice though, is that very little of this time is writing actual code for the library – our fantastic community of contributors is really driving that. We’re just making sure it gets delivered to people.
The trick is, between the paying jobs, family, and stuff that just comes up in life, all of us are kept pretty busy.
We’re actually not concerned about the time it would take to write the code for a new major version of Moment that was immutable. If we agreed upon a time frame, a couple of us could probably set aside the rest of life’s concerns for a couple weeks and get this done.
What we are concerned about is having two forks to maintain. From the outside, it’s easy to say “use SemVer, end of life the other fork, and move on”. We have too many users for this. The bottom line is that we can make as many ‘end of life’ and ‘end of support’ announcements about 2.0 as we want, and we can set as many timelines as we please. It won’t change the fact that Moment 2.0 will be in hundreds of thousands of code bases, if not more, for years to come. One need only look to the prevalence of websites still using jQuery 1.* versions to know this is true.
What this means is that we will still be getting GitHub issues, bug reports, Stack Overflow questions and possibly even pull requests on the 2.0 fork for (potentially) years. And unlike jQuery , we don’t have a foundation backing us to help us have the time to answer these.
And as I said in the beginning, we want to make people happy. So we really don’t want to tell everyone ‘too bad, so sad, upgrade to the newest immutable version.’ Because we’re all coders at our day job. And we all know how difficult it can be to get ‘upgrade JavaScript library’ on a development schedule, especially when that library has made a change like moving to immutability, where potentially every line of your code that uses the library could be affected.
In the face of all that, with the mutability vs immutability issue, it all comes down to this one fact:
The mutable library does what people need it to do.
In writing this library, Tim (the author), Iskren (the current lead), and the rest of the community managed to improve millions of code bases. People use it every day. It solves their problems.
An immutable API would be better. But would it be so much better that we should tell all of the users we have out in the world that we can’t support their (working) code as it is today?
We haven’t ruled out immutability. Maybe it is worth it. It will remain in discussion, along with work-arounds like making this plugin an official plugin that ships with the library, which is frankly a more likely route. But this is why it hasn’t happened yet.
I would ask anybody who is rallying for immutability in Moment this question:
Do you want Moment to be immutable, or is Moment not the library you want?