Bake-off: How to pick the right front-end JavaScript library
This July the MindTouch engineering team organized a fun and (we think) interesting way to decide on a front-end JavaScript framework or library to use for one of our upcoming projects. It was considered a pretty big decision, because if this project proves successful, we plan to use the next opportunity to start including the same library / framework throughout new features in our core product, which means that many developers will experience the joys or pains of the decision throughout their workday for years to come.
This article is about the process of making the decision, and should not be considered a universal endorsement of the library we ended up choosing, or a condemnation of the ones we didn’t. Choosing the right stack depends highly on the problem you’re trying to solve, expertise available in your company or (local) labor pool, and many other factors.
By making this decision in a hackathon-style bake-off format, we know we made the right decision, and we’re making front-end development at MindTouch better for years to come.
We hope that by sharing our experience, we can increase your odds of making the right decision for your project.
Why now?
We got along fine without using a front-end JS framework for the past decade, so it’s probably helpful to understand why we’re doing this now. If you don’t care, just skip to “The bake-off”.
Why we weren’t using front-end framework already
MindTouch front-end JavaScript code today is very vanilla. At some point, we used to have jQuery in there, but in the past year, we even ripped that out; probably for the best in 2019… There is a longstanding tradition of this pure approach within MindTouch Engineering, and there are some clear benefits. For instance, performance is great when every byte of code loaded is actually used; something that’s much harder to achieve with your average framework- or library based app. It’s also very helpful if the people who wrote the code that makes up large portions of your app, are able to make changes when you need it, without having to worry about increasingly difficult upgrades because your improvements haven’t made it into the main OSS (Open Source Software) project yet. We’re not of the opinion here that OSS is bad; quite the contrary. Much of our core product infrastructure is built on OSS, and we have released various frameworks as OSS ourselves. The point here is that relying on a large stack of OSS can result in less control compared to software you write yourself.
So why did we decide to look for a front-end JS library / framework to adopt now?
Speed and ease of development
People love working with OSS because it’s free, community driven, and keeps you from having to reinvent every single wheel. It can be a real power tool, and speed up your product and feature delivery by many factors. If you pick popular OSS frameworks and libraries to work with, it can also make it easier for (new) developers to read- and understand code written by other developers: If a developer joining your team can recognize the conventions and common patterns in your code, because they’ve worked with the libraries / frameworks before, you can shorten their ramp up time a lot.
Tooling and maintainability
Let’s be frank: It’s easy to make a mess of JavaScript. As the Swiss army knife of languages, it just lends itself well for wrongly applied patterns, and without additional tooling to help organize the various parts of your application, it’s also easy to end up with a bowl of spaghetti. It’s not all JavaScript’s fault: it just happens to be one of the languages that junior developers first learn, and we all have to make some mistakes early on to get better at this stuff over time. This is part of JavaScript’s reputation, though, and some of it is deserved. What can really help is a framework that makes it easier to organize code into components and libraries, and tools that help with “building”, deploying, static analysis, etc. A framework that works well with robust tools, increases your chances of maintaining a stable and secure application over time. Over the years we have built many tools and conventions to keep our JS code maintainable, but it’s a tax we have to continuously pay, and using a well-tooled OSS framework can give us the same benefits at a much lower cost.
Recruiting
Whether we like it or not, hiring managers have to deal with the fact that front-end frameworks rise and fall in popularity, and this affects our ability to recruit. If you picked a front-end framework 3 or more years ago, and haven’t kept up with the times, your ability to get people excited about your open positions is not going to get any better… I’m certainly not advocating for blindly following the trends in the market, because you’d have to completely rebuild your application every few years, but you should factor it into any framework / library decisions you make. For us, making recruiting easier was one of the key factors in deciding which one to go with. If the framework / library is not popular, and most people didn’t like working with it, we pass on it.
The bake-off
Because the decision of which framework / library to use would impact many team members, we wanted to make sure we’d end up with a decision that everyone could support. The tools we pick are a critical part of the developer experience on our team, and developer experience is very important at MindTouch engineering. An outcome where some of us feel like they “won” and some like they “lost” would be potentially bad for morale, so we tried to construct the decision-making process in a way that would prevent that. Even worse would be if team members didn’t like the outcome, and felt like they had no control over it whatsoever.
It’s worth noting that 99% of these types of decisions are made by 1 or maybe 2 people, without much input from others. This can be a great source of frustration for other engineers, and we deliberately structured our decision making process to be different.
We leaned on our experience with collaborative problem solving, which is a key part of our monthly hackathon: LambdaSharp (but with a twist). Instead of the usual single 3 hour mob-programming challenge, we took a full week with 3 senior software engineers, and asked all 3 to work on competing projects, each implementing the same UI with their framework / library of choice. We wanted to make sure everyone who was part of making the decision, would be able to do so based on practical experience building something real (not just research and strongly held opinions based on some personal projects). Even better: it would be based on a shared experience, where each of the 3 developers worked on each of the 3 projects.
Here are the 3 developers and the frameworks / libraries they brought to the challenge:
- Brittan McGinnis: React + Redux
- Spencer Kittleston: VueJS
- Adam Patten: Polymer / LitHTML / LitElement
Wait, what?!? You took 3 developers offline for a week to do this thing?
Yes, and it’ll probably be the best use of 3 developer-weeks this year. Why? Well, how much will it cost to live with the wrong decision? Have you ever been many developer-years into product development, wishing you could rewind the clock and spend a little more time upfront evaluating your choice of stack? Right…
Day 1: Setup
On the first day, we set up the challenge by:
- Creating a mock API to build the UI on top of
- Creating a GitHub project board for each of the 3 projects, all with the same user stories to implement
- Creating some simple mock ups for the UI
The challenge itself revolved around a rebuild of an internal tool called Portal, which we use to manage sites on our platform. It’s a powerful tool, but with a simple UI. It doesn’t have that many users, so it makes for a good testing ground for new technologies to use. We decided to use this tool as the first place to apply a new front-end JS library or framework, and if we like it, may use the same for features of our core product.
Day 2: Out of the starting gates
The 3 developers got started on their projects, and implemented as many user stories as possible. How far they were able to get on day one was considered the main data point to measure learning curve and tooling support. Even though a single engineer ever only has to get started with a project once, when you add up the ramp up time for every engineer who has to get started working on the same application over time, it starts adding up. Most of our engineers like variety, and we let them switch projects / apps every quarter, so it’s important that people can jump into something and be effective almost immediately.
As you can see, there was a pretty dramatic difference at the end of day one:
Spencer was able to implement nearly all of the user stories using VueJS on his first day of coding. Brittan got through about half of them using React, and Adam was only just getting started with Polymer. To be fair, Polymer was new to Adam, whereas Brittan and Spencer had prior experience with their chosen stack, but as you’ll see later on, that only explains part of the difference.
Days 3 and 4: Switcheroo
This is where things got interesting: All 3 developers had to switch projects, and pick up where the previous developer had left off. They’ll do it again on Day 4, so that at the end of the week, every dev had worked on all 3 projects. The reason we did this is that reading other people’s code, trying to make sense of it, and modifying it, is something that’s both one of the more difficult and most common parts of a developer’s day-to-day experience. It’s something we don’t normally do in our LambdaSharp hackathon, because we only have a few hours. Etienne de Bruin and I started doing this with the 1618 Mob Programming hackathons here in San Diego, where we build some sort of app in several evenings, and swap team members every time. It’s really fun.
Here’s why we do it: Green field projects can be fun, but the reality is that (senior) software engineering is mostly a brown field affair, meaning you have to build on someone else’s code. So we made that part of this challenge too, because remember: we’re trying to test these frameworks building something real, in a realistic manner.
To make this just a bit more challenging, we didn’t allow for a warm handover. Any important information that the next developer would need to know, had to be put in the project’s readme file on the day before. What we found was that Spencer and Brittan could just link to some articles and code samples published online, as well as the React- and Vue project documentation, and save themselves a lot of time. With Polymer this was not the case. Things weren’t so clear.
To keep the engineers from losing a full day getting stuck on a single issue (which could easily happen), we added the rule that if you got stuck for 30 minutes, you should ask the engineer who chose the project you were working on for help. The leading “I’ve fallen and I can’t get up” project was Polymer; all 3 engineers got stuck with it. Brittan commented that “Polymer seems like what you’d get if the government created a front-end library”. If you’re not familiar with general sentiment towards the quality of government work here in the U.S.: This is not a compliment…
Day 5: Demo and duking it out
On the morning of day 5, each engineer got an hour or two to clean up the “mess” that the other engineers made of their code, and get it ready for a demo. As is common in our hackathon format, at the end you demo the work product, and walk an audience through your code. We did that in front of the whole engineering team, and other interested MindTouchers. It’s a really good way of learning from each other, just openly showing your work and taking questions / comments, and it reinforces our open engineering culture.
After the demo it was time to finally make some decisions. To help facilitate the decision making, we defined the criteria up front:
- Learning Curve (implicit: documentation)
How easy will it be for new developers to become effective? - Momentum / Interest / Community
How easy will it be now, and in the next 3 years to hire developers? - Tooling / Features / Package ecosystem
How much faster will we be able to build new product features with this tool? - Maintainability / Upgradeability
How far will this framework help us scale without major rework? - Evolutionary integration into existing MindTouch UI
(How) can we use this framework to gradually update the MindTouch UI?
We each scored the 3 libraries individually on these 5 criteria, and added up the scores.
They were surprisingly close:
- VueJS: 56
- React: 55
- Polymer: 47
Even though I didn’t participate in the coding challenge, I did score the 3 libraries myself as well, based on (developer) market research. Part of the assessment was to gauge how new developers would fare with our library of choice, and how this would help attract them in the first place. To assess that, I used the stateofjs survey results, information from Meetup.com, as well as my own research on LinkedIn looking at open positions and resumes referencing these libraries. The highlights of that research are at the bottom (as not to clutter this up).
I’ll note here that if the team of engineers was about to seriously consider going with Polymer (spoiler: they didn’t), I would have had to challenge that. I was not able to find a single job opening listing Polymer anywhere. More importantly, in the state of JS survey, experience and interest in Polymer had been low for years, and nearly 1 in 2 people who had used it, did not want to use it again. That’s pretty bad. I’m not bringing this up to dish on Polymer, which is a formidable project run by extremely talented and accomplished people. Ironically, it’s what we were probably going to go with before this exercise. The reason I’m bringing it up, is to point out that there’s readily available information out there about how people feel about these frameworks, and it would be foolish not to use it.
So, who won?
In the end, we asked each of the 3 engineers to stack rank the libraries, and we got our winner:
It was clear that VueJS was the favorite, and although it wasn’t Brittan’s first choice, he was excited about where we landed.
Some of the things we liked about VueJS was its pragmatism. You can start small (and simple!), and transform your architecture as your application grows. It also seems that there’s great support for evolving an existing application, as opposed to starting from scratch, which was a specific requirement for us. We liked the way the VueJS team designed certain features, like 2-way data binding for instance, with a natural and familiar syntax.
Following our decision, we went into an interesting discussion on how we could take parts of each project, and combine them, to make our winning stack even better:
Everyone loved Redux, which actually plays nicely with VueJS, so we considered including that in the final stack for state management. By now we’re actually building our first app with VueJS, and decided to go with Vuex instead (very similar), but it was really great to see us immediately -and quite organically- go into an exploration to find some “1+1=3” opportunities.
Adam suggested we might also be able to include LitElement (part of the Polymer project) for rendering, which would give us standard web components as part of the generated HTML / JS: something that could future-proof us for the glorious moment when it’s finally supported by all major browsers. This is still an open option, and we might go this route when we’re integrating VueJS into our core application.
In the end, though, and this might sound cheesy in a participation-ribbon kind of way, we all felt like winners. What we ended up with wasn’t a watered-down compromise, but more of watered-up compromise (if there is such a thing). It was an exhausting week for everyone involved, but the outcome was a broad understanding and appreciation of the strengths and weaknesses of each library. The format we used achieved its goal, and we have high confidence that the libraries we chose will work well for us for years to come.
References
We give credit to some amazing projects and posts by others that inspired us:
- https://2018.stateofjs.com/
- https://www.freecodecamp.org/news/the-12-things-you-need-to-consider-when-evaluating-any-new-javascript-library-3908c4ed3f49/
- http://todomvc.com/
Industry- and market research
To gauge what the world outside of MindTouch thinks of these frameworks, I using LinkedIn to research job postings and developer profiles, Meetup to research local developer communities, and the stateofjs survey for high level perspective on the pros and cons of each framework. You can find some of the results below.
LinkedIn analysis
I used LinkedIn to find local (Greater San Diego area) job listings and developer profiles that mention each of the frameworks. Using the developer profiles I found, I also estimated what percentage of them were considered “senior” engineers (by filtering by common senior engineering titles).
Some highlights:
- React is by far the most used- and recruited for framework, and ranks in the middle with regards to seniority of engineers who have experience with it.
- VueJS is recruited for (mentioned in job listing) only about 1/8th of the jobs out there compared to React, and 1/5th of engineers list it on their resume compared to React.
- Not a single job listing in San Diego requires Polymer experience, and about the same number of engineers list it on their resume as VueJS.
- Engineers with Polymer experience tend to be the most senior, followed by React, with VueJS listed on the most junior resumes (the differences are pretty small, though).
State of JS & Meetup analysis
The lovely stateofjs survey sure made this part easy. I could just look up their analysis, and pick out a few of the highlights. You can see screen shots and the highlights per framework below. As for gauging the community support for the frameworks, I checked Meetup.com for past- and current meetup groups.
React
- 65% used it, and would use it again, with steady growth year over year
- 10% is not interested, steady year over year
- 7% would not want to use it again
People Like:
- Rich package ecosystem
- Well-established option
- Good documentation
San Diego React & React Native meetup has 163 members and had 1 meeting on 5/2/19
VueJS
- 28% used it, and would use it again, with steady growth year over year
- 47% want to use it, but haven’t yet
- 10% is not interested, steady year over year
- 3% of people would not want to use it again
People Like:
- Easy learning curve
- Good documentation
- Simple and lightweight
San Diego VueJS meetup recently merged with the San Diego JS meetup, and doesn’t exist as an independent meetup anymore
Polymer
- 4% used it, and would use it again, down 1% from last year
- almost 50% of people who have used it, do not want to use it again
- 50% of people have heard of it, and are not interested, up from about 40% last year
People Like:
- Simple and lightweight
- Backed by a great team
- Easy learning curve
There is no, and never has been, a Polymer meetup in San Diego (as far as we can tell)