Recently I published an article about the usage of top front end JavaScript frameworks. The two things that stood out were the dominance of React and the explosive growth of Vue. If current trends continue, it seems likely that by this time next year, Vue will have overtaken Angular as the second most used library or framework.

I've been using React for the last three years building websites for a client services company. Most of the time, the client comes to us specifying that they want to use React. However, it seems only a matter of time before Vue is a bigger part of those discussions. What follows is my first pass at better understanding the differences between these two libraries so I can give better advice to our clients.

Even though I’ve worked with React for three years and enjoy it, I will try to be as even-handed as possible in what follows, although some knowledge gaps with Vue may inadvertently arise.

Beginning at the End

I’ll start with my conclusions. React and Vue are rather similar, although there are some key differences which I’ll discuss shortly. This makes sense as Evan You, the developer of Vue, used React as one of his inspirations. They are much more like one another than they are to say, Angular or Ember. From the Vue documentation, we see that both:

  • utilize a virtual DOM
  • provide reactive and composable view components
  • maintain focus in the core library, with concerns such as routing and global state management handled by companion libraries

From the standpoint of a finished product, I don’t think clients (or product owners) would be able to tell much difference if their app was built using Vue or React. They are similar in performance and they are both capable of being used on projects large and small.

If you want to publish content across multiple platforms - web and mobile, for example - then React has the edge due to the excellent React Native. My colleagues have also used React to build embedded apps for TVs, which is an interesting example of another platform where you might use React. Vue does have a native mobile option in Weex, however, so perhaps it would work for your situation.

React also has a much larger ecosystem, which can potentially help accelerate development. If you need a key feature or behavior for your app, chances are someone in the React community has already made a solution for it. In fact, you’ll probably find several solutions.

Another consideration for the type of clients my company works with is the ability to find developers that are well-versed in the library/framework they are investing in. React has the advantage here as well, although I think this is likely temporary.

The other differences are mostly developer preference. They involve paradigms that have trade-offs and I don’t see a clear right or wrong answer. I’ll discuss those in the next section.

Bottom line:
If you have a team that is already familiar with React, there is no net advantage to switching to Vue (caveats below). If you have a team that is building front end applications for the first time or are thinking of migrating away from a framework like Backbone or AngularJS, then you should consider Vue, although React retains the advantages I noted above. The other factors rest with developer preferences which I’ll discuss next.

The Differences

The best place to start looking at the differences between React and Vue comes from the Vue documentation (very good) which addresses the topic quite well. It’s particularly useful because it was written by Evan You in cooperation with Dan Abramov, a member of the React team. It also works as a nice counter balance to any biases I may have.

Performance

Vue and React are similar in performance. The Vue docs say it has a slight advantage in most cases, however, recent benchmarks show React 16 having the edge over Vue 2.5. When optimizing performance there are some differences…

In React, when a component’s state changes, it triggers the re-render of the entire component sub-tree, starting at that component as root. To avoid unnecessary re-renders of child components, you need to either use PureComponent or implement shouldComponentUpdate whenever you can….

In Vue, a component’s dependencies are automatically tracked during its render, so the system knows precisely which components actually need to re-render when state changes. Each component can be considered to have shouldComponentUpdate automatically implemented for you, without the nested component caveats.

Overall this removes the need for a whole class of performance optimizations from the developer’s plate, and allows them to focus more on building the app itself as it scales.

Update on 19/12/17: After digging a bit deeper in a recent article, I need to revise my conclusion here. Vue is slightly faster, but it depends on what you're measuring. Follow the link for more details.

Templating vs JSX

Another big difference comes with Vue’s use of templates vs React’s JSX. Many developers don’t like templating languages. Vue’s response…

Some argue that you’d need to learn an extra DSL (Domain-Specific Language) to be able to write templates - we believe this difference is superficial at best. First, JSX doesn’t mean the user doesn’t need to learn anything - it’s additional syntax on top of plain JavaScript, so it can be easy for someone familiar with JavaScript to learn, but saying it’s essentially free is misleading. Similarly, a template is just additional syntax on top of plain HTML and thus has very low learning cost for those who are already familiar with HTML. With the DSL we are also able to help the user get more done with less code (e.g. v-on modifiers). The same task can involve a lot more code when using plain JSX or render functions.

My concern is that if you are mixing JSX and a templating language, your app has more complexity. It’s easier to stick with one paradigm to avoid the overhead of context switching as you go from one component to the next. But reasonable people can disagree on this point.

CSS

The way Vue handles CSS is quite nice. The Vue docs begin by noting that CSS-in-JS is a very popular way of scoping CSS in React. Then it goes on to say…

If you are a fan of CSS-in-JS, many of the popular CSS-in-JS libraries support Vue (e.g. styled-components-vue and vue-emotion). The main difference between React and Vue here is that the default method of styling in Vue is through more familiar style tags in single-file components.

The single-file components that include CSS are what looks good to me. Below is a screenshot of a sample component from the docs. Notice the <style> tag at the bottom.

vue component

By including that tag in the component file, you get component scoped CSS and syntax highlighting. It’s also a bit simpler to implement that the CSS-in-JS solutions for React. Nice.

Ecosystem

As noted earlier, the React ecosystem is much larger than Vue’s. This is a benefit of using React, but it can also make it overwhelming for newcomers. Vue leaves less up to the community, instead keeping important libraries in sync:

Vue’s companion libraries for state management and routing (among other concerns) are all officially supported and kept up-to-date with the core library. React instead chooses to leave these concerns to the community, creating a more fragmented ecosystem. Being more popular though, React’s ecosystem is considerably richer than Vue’s.

State Management

For me, this is a key difference. One of the big paradigms in React is functional programming. If you use the popular Redux state management library alongside React, then you are largely working in a functional paradigm.

This is something that has been hugely influential within the larger JavaScript community in recent years. React didn’t invent functional programming - it’s quite an old concept. But it did popularize it with a new generation of programmers. It’s a powerful way of programming that has helped me write better code.

One of the tenets of functional programming is immutability. Here’s a recent talk that explains why immutability matters for reference, but the idea is to control what are called “side effects” and to make managing application state easier and more predictable.

Now, React itself is not a fully functional library by any means. There is also a popular state management library for React called MobX that has mutable state. From the Vue docs:

MobX has become quite popular in the React community and it actually uses a nearly identical reactivity system to Vue. To a limited extent, the React + MobX workflow can be thought of as a more verbose Vue, so if you’re using that combination and are enjoying it, jumping into Vue is probably the next logical step.


Another popular state management option with Vue is a library called Vuex. Here’s a quote from an article comparing Redux and Vuex that is helpful in illuminating the differences:

Similar to Redux, Vuex is also inspired by Flux. However, unlike Redux, Vuex mutates the state rather than making the state immutable and replacing it entirely like with Redux’s ‘reducer’ functions.

This allows Vue.js to automatically know which directives need to be re-rendered when the state changes. Instead of breaking down state logic with specialized reducers, Vuex is able to organize its state logic with stores called modules.

Although this is a fairly technical argument, to many developers paradigms matter. If working in a functional programming paradigm matters to you, then React will likely have more appeal (with the possible exception of those using MobX). If not, then Vue may be more attractive.

Other Insights

There were a recent series of tweets from Dan Abramov - in reply to a tweet that compared React unfavorably to Vue - that I think are worth sharing. Dan is part of the React team and there is a slight bias to his comments here, but they nonetheless offer insight regarding differences between React and Vue…


I end with a quote from Evan You. It’s taken from an interview he did with Vivian Cromwell. The question was about how Vue compares with other frameworks.

I think, in terms of all the frameworks out there, Vue is probably the most similar to React, but on a broader sense, among all the frameworks, the term that I coined myself is a progressive framework. The idea is that Vue is made up of this core which is just data binding and components, similar to React. It solves a very focused, limited set of problems. Compared to React, Vue puts a bit more focus on approachability. Making sure people who know basics such as: HTML, JavaScript, and CSS can pick it up as fast as possible.

On a framework level, we tried to build it with a very lean and minimal core, but as you build more complex applications, you naturally need to solve additional problems. For example routing, or how you handle cross component communication, share states in a bigger application, and then you also need these build tools to modularize your code base. How do you organize styles, and the different assets of your app? Many of the more complete frameworks like Ember or Angular, they try to be opinionated on all the problems you are going to run into and try to make everything built into the framework.

It’s a bit of a trade off. The more assumptions you make about the user’s use case then the less flexibility the framework will eventually be able to afford. Or leave everything to the ecosystem such as React — the React ecosystem is very, very vibrant. There are a lot of great ideas coming out, but there is also a lot of churn. Vue tries to pick the middle ground where the core is still exposed as a very minimal feature set, but we also offer these incrementally adoptable pieces, like a routing solution, a state management solution, a build toolchain, and the CLI. They are all officially maintained, well documented, designed to work together, but you don’t have to use them all. I think that’s probably the biggest thing that makes Vue as a framework, different from others.

If you’ve enjoyed this post, sign up for my weekly newsletter. I curate the best JavaScript writing from around the web and deliver it to readers every Thursday. The sign up form is right below this article.

Until next time, happy coding…