On March 6, 2018, a new bug was added to the official Mozilla Firefox browser bug tracker. A developer had noticed an issue with Mozilla’s nightly build. The report noted that a 14-day weather forecast widget typically featured on a German website had all of a sudden broken and disappeared. Nothing on the site had changed, so the problem had to be with Firefox.
At first glance, the bug appeared to be fairly routine, most likely a small problem somewhere in the website’s code or a strange coincidence. After just a few hours though, it became clear that the stakes for this one particular bug were far graver than anyone could have anticipated. If Firefox were to release this version of their browser as-is, they risked breaking an unknown, but still predictably rather large number of websites, all at once. Why that is has everything to do with the way MooTools was built, where it drew influence from, and the moment in time it was released. So to really understand the problem, we’ll have to go all the way back to the beginning.
In the beginning
Prototype went through a few iterations in rapid succession, gaining significant steam after it was included by default in all Ruby on Rails installations not long after its release. Along the way, Prototype set the groundwork for basically every framework that would come after it. For instance, it was the first to use the dollar sign (
Prototype had its fair share of competition from other libraries like base2 which took the object-oriented bits of Prototype and spun them off into a more compact version. But the library’s biggest competitor came when John Resig decided to put his own horse in the race. Resig was particularly interested in that last bit, the work-in-all-browsers-with-the-same-code bit. He began working on a different take on that idea in 2005, and eventually unveiled a library of his own at Barcamp in New York in January of 2006.
It was called jQuery.
It might sound small, but that slight paradigm shift was truly massive. A shift that seismic required a response, a response that incidentally came the very next year, in 2007, when Valerio Proietti found himself entirely frustrated with another library altogether. The library was called script.aculo.us, and it helped developers with page transitions and animations. Try as he might, Proietti just couldn’t get script.aculo.us to do what he wanted to do, so (as many developers in his position have done in the past), he decided to rewrite his own version. An object-oriented developer himself, he was already a big fan of Protoype, so he based his first version off of the library’s foundational principles. He even attempted to coast off its success with his first stab at a name: prototype.lite.js. A few months and many new features later, Proietti transformed that into MooTools.
There was plenty there from jQuery too. Like jQuery, MooTools smoothed over inconsistencies and bugs in the various browsers on the market, and offered quick and easy ways to add transitions, make server requests, and manipulate webpages dynamically. By the time MooTools was released, the jQuery syntax had more or less become the standard, and MooTools was not going to be the one to break the mold.
There was enough similarities between the two, in fact, for them to be pitted against one another in a near-endless stream of blog posts and think-pieces. MooTools vs. jQuery, a question for the ages. Websites sprung up to compare the two. MooTools was a “framework,” jQuery was a “library.” MooTools made coding fun, jQuery made the web fun. MooTools was for Geminis, and jQuery was for Sagittariuses. In truth, both worked very well, and the use of one over the other was mostly a matter of personal preference. This is largely true of many of the most common developer library debates, but they continue on all the same.
The legacy of legacy frameworks
Ultimately, it wasn’t features or code structure that won the day — it was time. One by one, the core contributors of MooTools peeled off from the project to work on other things. By 2010, only a few remained. Development slowed, and the community wasn’t far behind. MooTools continued to be popular, but its momentum had come to a screeching halt.
jQuery’s advantage was simply that they continued on, expanded even. In 2010, when MooTools development began to wind down, jQuery released the first version of jQuery Mobile, an attempt at retooling the library for a mobile world. The jQuery community never quit, and in the end, it gave them the advantage.
The legacy and reach of MooTools, however, is massive. It made its way onto hundreds of thousands of sites, and spread all around the world. According to some stats we have, it is still, to this day, more common to see MooTools than Angular or React or Vue or any modern framework on the average website. The code of some sites were updated to keep pace with the far less frequent, but still occasional, updates to MooTools. Others to this day are comfortable with whatever version of MooTools they have installed. Most simply haven’t updated their site at all. When the site was built, MooTools was the best option available and now, years later, the same version remains.
Array.flatten, starting with the beta release of Firefox.
The problem was that Firefox’s
Array.flatten didn’t map directly to the MooTools version of
flatten. Essentially, to let the old sites break. There was, it was argued, a simple elegance to the proposal, backed fundamentally by the idea that it is the responsibility of browsers to push the web forward. Breaking sites would force site owners to upgrade, and we could finally rid ourselves of the old and outdated MooTools versions.
Others quickly jumped in to point out that the web is near limitless and that it is impossible to track which sites may be affected. A good amount of those sites probably hadn’t been updated in years. Some may have been abandoned. Others might not have the resources to upgrade. Should we leave these sites to rot? The safe, forgivable approach would be to retool the function to be either backward or fully compatible with MooTools. Upon release, nothing would break, even if the final implementation of
Array.flatten was less than ideal.
Somewhere down the middle, a final proposition suggested the best course of action may simply be to rename the function entirely, essentially sidestepping the issue altogether and avoiding the need for the two implementations to play nice at all.
One developer suggested that the name
Array.smoosh be used instead, which eventually lead to the whole incident to be labeled Smooshgate, which was unfortunate because it glossed over a much more interesting debate lurking just under the surface about the very soul of the web. It exposed an essential question about the responsibility of browser makers and developers to provide an accessible and open and forgiving experience for each and every user of the web and each and every builder of the web, even when (maybe especially when) the standards of the web are completely ignored. Put simply, the question was, should we ever break the web?
To be clear, the web is a ubiquitous and rapidly developing medium originally built for sharing text and links and little else, but now used by billions of people each day in every facet of their lives to do truly extraordinary things. It will, on occasion, break all on its own. But, when a situation arises that is in full view and, ultimately, preventable, is the proper course of action to try and pull the web forward or to ensure that the web in its current form continues to function even as technology advances?
This only leads to more questions. Who should be responsible for making these decisions? Should every library be actively maintained in some way, ad infinitum, even when best practices shift to anti-patterns? What is our obligation, as developers, for sites we know have been abandoned? And, most importantly, how can we best serve the many different users of the web while still giving developers new programmatic tools? These are the same questions that we continue to return to, and they have been at the core of discussions like progressive enhancement, responsive design and accessibility.
Where do we go now?
It is impossible to answer all of these questions simply. They can, however, be framed by the ideological project of the web itself. The web was built to be open, both technologically as a decentralized network, and philosophically as a democratizing medium. These questions are tricky because the web belongs to no one, yet was built for everyone. Maintaining that spirit takes a lot of work, and requires sometimes slow, but always deliberate decisions about the trajectory of web technologies. We should be careful to consider the mountains of legacy code and libraries that will likely remain on the web for its entire existence. Not just because they are often built with the best of intentions, but because many have been woven into the fabric of the web. If we pull on any one thread too hard, we risk unraveling the whole thing.
Array.flatten was renamed to
Array.flat, and is now active in most modern browser releases. It is hard to say if this was absolutely the best decision, and certainly, we won’t always get things right. But if we remember the foundational ideals of the web — that it was built as an accessible, inclusive and always shifting medium, and use that as a guide — then it can help our decision-making process. This seems to have been at the core of the case with Smooshgate.
Enjoy learning about web history with stories just like this? Jay Hoffmann is telling the full story of the web, all the way from the beginning, over on The History of the Web. Sign up for his newsletter to catch up on the latest… of what’s past!
Absolutely genious to read. If only half of the things i have to read for my job was crafted like this post, I’d click on every post in my rss feeds :D
Well done. Also because you didn’t opinionate in the bend-or-break discussion.
Ultimately though, the web is held back when it must bend instead of break.
Our code should never be changing browser native prototypes like that. We hold things back otherwise.
Yet when millions of sites relying on flash broke, no one cared.
And that kids is why you never add custom methods to a native prototype.
That was also a reason why jQuery won. It made more sense
it’s terrible: we can’t have nice things cause that would break the ugly ones and we can’t allow that
Excellent article! Love the fascinating history lesson!
Interesting that this was published the same day as a piece the BBC did on the problems of archiving the early internet. What some describe as a technical “rot” may well be the cause for the destruction of content.
Why is this always related to the “prototype”. Other languages that don’t use prototypical inheritance let you modify system types. Its just, does the language/compiler let you do this. It has nothing to do with prototypical inheritance
Solution is: allow javascrip versioning. At the top of the file, the dev writes // js-x.y.z or just // js-x or // ecma-xxxx
End of story
That was interesting. My own instinct would’ve been to hack pseudo-support for Prototype.
To detect if the old flatten exists and if so to leave it be. But if not… Don’t stop moving the net forward.
Maybe add a console warning to those old sites that their version of flatten is deprecated, and that they really should switch.
So that the sites that still have developers will fix them.
Overall, it’s not good to hold the net back and stop people from having access to features they should.
Such an amazing read!
As a developer working in an agency, i build websites for a large quantity of people, these sites need to work on many different phones and browsers, when it comes to browsers, my team still supports IE11, mainly because it is still supported by Microsoft, we had many discussions of dropping that support, but we ultimately choose to maintain, but client is always warned if a particular feature is just not supported there.
I feel when creating new stuff, we must do new things, but these old websites, care or not, someone is still probably paying the domain or the content there is relevant in some way to someone, we must try to coexist with these old works.
I don’t think it’s ultimately solvable. Web is a medium for all, and situations for compromises will arise through all its possible timeline. Responsibility lies on everyone – developers, browser makers, and ‘users’.
Healthy thing here is that decision was made consciously.