Vue vs React: Battle of the Javascript Frameworks

As we’ve mentioned before here, the WordPress core team is debating which JavaScript framework to add to the existing set of frameworks. React and Vue.js appear to be front-runners, with many members of the community discussing the pros and cons of these two frameworks.

So which framework rocks and which framework is the new prototype.js.? Let’s find out.

I’ve created two nearly identical sample applications, one in Vue and one in React, if you’d like to give either framework a shot in the context of the samples in this article.

The Contenders

Unless you’ve been hiding under a rock for the past couple years, you’ve likely heard of the JavaScript UI framework developed at Facebook called React. It powers most of the Facebook website as well as Instagram. React was a bit of change in the JavaScript world when it came out as it’s quite different from other at-the-time frameworks like jQuery, Backbone.js and Angular 1. The biggest difference is that React popularized a Virtual DOM (we’ll get into this later) and created a new syntax called JSX that allows developers to write HTML in JavaScript. WAT?

Vue.js is a similar JavaScript framework that aims to tackle the same problems as React but in a different way. Vue uses a template system instead of JSX, arguably making it easier to integrate into existing apps. Because the templates use regular HTML Vue can be integrated into existing code quite easily, without the need for a build step. Vue is also said to be easier for new developers to pick up as well – something that I’ve recently verified as I’m new to Vue. The other main thing to mention about Vue is that it’s mostly maintained by a single developer rather than being backed by a large corporation like Facebook.

Similarities

React and Vue have a lot in common as they’re both UI JavaScript frameworks focused solely on creating rich front-end experiences. Unlike earlier JavaScript frameworks that had ‘batteries included,’ both React and Vue are fairly barebones with functionality like routing and state management handled by separate frameworks.

Usage of a Virtual DOM

Ahh, the oft spoken-about Virtual DOM.

DOMS, DOMS EVERYWHERE

One of the biggest similarities between Vue.js (as of version 2.0) and React is the usage of what’s called a ‘Virtual DOM’. A Virtual DOM is basically what it sounds like, a virtual representation of the DOM tree. It hinges on the concept that updating the real DOM frequently is computationally heavy. Updating JavaScript objects is relatively lightweight by comparison.

With a Virtual DOM, a JavaScript object representing the real DOM tree is created. Updates to any element are made in the Virtual DOM rather than the real DOM. When something is changed, a new Virtual DOM object is created and the changes between the old and new are determined. These changes are then applied to the real DOM.

For example let’s take this list in HTML:

<ul class="list">
  <li>item 1</li>
  <li>item 2</li>
</ul>

In JavaScript this could be represented simply as:

{
    type: 'ul', 
    props: {'class': 'list'}, 
    children: [
        { type: 'li', props: {}, children: ['item 1'] },
        { type: 'li', props: {}, children: ['item 2'] }
    ]
}

Actual Virtual DOM implementations are more complex than this, but they’re essentially a nested JavaScript object with nested arrays.

When a new item is added to this JavaScript object a function will ‘diff’ the changes and apply the new markup to the real DOM. This ‘diffing’ algorithm is the secret sauce, and both React and Vue do this a bit differently.

Vue is reported to be able to diff changes to the Virtual DOM more quickly as it keeps track of each component’s dependencies during render, not needing to re-render a whole component’s sub-tree.

With React, child components will all be refreshed each time application state is changed. This can be overridden by using the shouldComponentUpdate lifecycle method, but Vue handles this kind of optimization by default.

Note: Using a Virtual DOM is only a good idea if you’ve got a large application making many updates to the UI. If you’re only updating elements infrequently it’s probably overkill and could very likely be slower than updating the DOM directly.

Component Based Architecture

Both React and Vue encourage a component based architecture. This essentially means separating your application into distinct chunks of related functionality with a defined way for each chunk to ‘talk’ to each other. A good explanation of what a component is can be found in this Medium article:

You can think of a component as a small feature that makes up a piece of the user interface. If I were to describe a component within the scope of Facebook’s UI, A chat window would be a component, a comment feed would be another component, and a constantly updating friend list would represent yet another component.

In Vue, you can use single file components that follow this principle.

//PastaItem.vue

<template>
<li class="pasta-dish list-unstyled">
    <div class="row">
        <div class="col-md-3">
            <img :src="this.item.image" :alt="this.item.name" />
        </div>
        <div class="col-md-9 text-left">
            <h3>{{this.item.name}}</h3>
            <p>
                {{this.item.desc}}
            </p>
            <button v-on:click="addToOrderNew" class="btn btn-primary">Add to order</button> <mark>{{this.orders}}</mark>
        </div>
    </div>
</li>
</template>

<script>

export default {
    name: 'pasta-item',
    props: ['item'],
    data:  function(){
        return{
            orders: 0
        }
    },
    methods: {
        addToOrderNew: function(y){
            this.orders += 1;
            this.$emit('order');
        }
    }
}

</script>

<style src="./Pasta.css"></style>

As you can see in the above example HTML, JavaScript and CSS are combined in one file. You don’t have to include CSS in your component .vue files, but it’s an option.

In React it’s very similar, with JavaScript and that fun JSX markup in a component file.

import React from "react";

class PastaItem extends React.Component {

    render() {
        const { details, index } = this.props;

        return (
            <li className="pasta-dish list-unstyled">
                <div className="row">
                    <div className="col-md-3">
                        <img src={details.image} alt={details.name} />
                    </div>
                    <div className="col-md-9 text-left">
                        <h3>{details.name}</h3>
                        <p>
                            {details.desc}
                        </p>
                        <button onClick={() => this.props.addToOrder(index)} className="btn btn-primary">Add to order</button> <mark>{this.props.orders || 0}</mark>
                    </div>
                </div>
            </li>
        );
    }
}

export default PastaItem;

Props

As in the above example, both React and Vue have a concept of ‘props’, which is short for properties. These are special attributes on an element that allow for the passing of data from parent to child.

Object.keys(this.state.pastadishes).map(key =>
    <PastaItem index={key} key={key} details={this.state.pastadishes[key]} addToOrder={this.addToOrder} orders={this.state.orders[key]} />
)

In the above JSX example the index, key, details, orders and addToOrder attributes are props passing data to the child PastaItem component.

In React this is necessary as it relies on a local ‘state’ (more on that later) that acts as a ‘single source of truth’.

In Vue, props are slightly different. They’re defined on a component in the same way, but since Vue relies on a template syntax, how you pass in data is a little more tricky and you have to use the built-in template loop functions.

<pasta-item v-for="(item, key) in samplePasta" :item="item" :key="key" @order="handleOrder(key)"></pasta-item>

It’s a little more on the ‘templatey’ side of things, but it gets the job done and I find it about as complex as the React version.

Build Tools

Both React and Vue have bootstrap applications that get you up and running quickly with your development environment. In React this is Create React App (CRA) and in Vue it’s vue-cli. In both cases you get a project template set up according to the latest best practices.

With CRA you’re a little more handcuffed as far as options. It’s an opinionated tool, forcing you to use Webpack and Babel out of the box. With vue-cli, you have options in the form of templates which makes it a little more flexible.

In reality though, both bootstrap tools are awesome and give you a solid and modern starting point to get you coding. Anything that doesn’t make you configure Webpack is a win in my (and Jeff’s) book.

enter image description here

Chrome Devtools

Both React and Vue also have awesome Chrome extensions to help in debugging. They let you inspect your application as you would any other website, but they allow you to see the Vue or React version of the markup. You’re also able to see application state data and see updates happen in real time.

React devtools in action:

Vue devtools in action:

Companion Frameworks

One last similarity (and difference) between these two frameworks is how they handle companion frameworks. Both React and Vue are focused solely on the UI layer, and leave functionality such as routing and state handling to companion frameworks.

The difference between Vue and React is how they relate to their respective companion frameworks. The Vue core team maintains the vue-router and vuex frameworks and keeps them under the main Vue umbrella. React’s react-router and react-redux are maintained by community members and aren’t ‘officially’ under the Facebook/React umbrella.

Main Differences

While Vue and React have a lot in common, there are some major differences.

Templating vs JSX

The biggest difference between React and Vue is how templating is done. In Vue, you’re encouraged to use regular-old-HTML for templating. This approach leverages custom attributes on standard HTML elements.

<ul>
    <template v-for="item in items">
        <li>{{ item.msg }}</li>
        <li class="divider"></li>
    </template>
</ul>

The attributes can also be used on single file components, although it requires a build step to convert the component syntax to valid JavaScript and HTML.

<ul>
  <pasta-item v-for="(item, key) in samplePasta" :item="item" :key="key" @order="handleOrder(key)"></pasta-item>
</ul>

Vue encourages the use of HTML to render things, while it uses a familiar Angular-style method for outputting dynamic content with Mustache-style syntax. For this reason, Vue is arguably easier to integrate into existing applications as you can very simply incorporate Vue templates into existing templates without too much overhead. This also reportedly makes it easier for newcomers to adapt to this syntax.

React on the other hand recommends you write all your template code in JavaScript by using a ‘syntax extension to JavaScript’ called JSX. For example, the same code in JSX:

<ul className="pasta-list">
    {
        Object.keys(this.state.pastadishes).map(key =>
            <PastaItem index={key} key={key} details={this.state.pastadishes[key]} addToOrder={this.addToOrder} orders={this.state.orders[key]} />
        )
    }
</ul>

React/JSX definitely appears more verbose at first glance, but by adding the ability to use JavaScript within templates a lot more power is given to the developer.

But remember:

With great power comes great responsibility. Ben Parker

JSX is really just JavaScript with some funny XML syntax. However, once you get used to it, it feels a lot more flexible and robust. This might be my own biases coming through, but I feel this is a better approach as I was never a fan of the Angular 1 style attribute mess.

The counter argument is that Vue’s template syntax removes the temptation to pile additional logic into your views/components, maintaining a separation of concerns.

It should also be mentioned that Vue does technically support render functions and JSX, like React, but they’re not the default approach.

State Management vs Object Properties

If you’re familiar with React you’ll know that application state is a key concept. There’s even frameworks dedicated to managing large scale state objects like Redux. Additionally, state data in React applications is immutable, meaning that it can’t be changed directly (though this isn’t exactly true). In React you need to use the setState() method to modify anything in the local state.

 addToOrder(key) {
        //Make a copy of this.state
        const orders = { ...this.state.orders };

        //update or add
        orders[ key ] = orders[ key ] + 1 || 1;
        this.setState( { orders } );
 }

With Vue a local state object isn’t required, and data is managed via the data property on the Vue object.

export default {
  name: 'app',
  data() {
    return {
      samplePasta: samplePasta,
      orders: {}
    }
  },
...
  methods: {
    handleOrder: function (key) {

      if (!this.orders.hasOwnProperty(key)) {
        this.$set(this.orders, key, { count: 0 });
      }

      this.orders[key].count += 1;
    }
  }
}

In Vue there’s no need to call a state management function like setState(), as the data parameter on the Vue object acts as the holder for application data.

On the topic of state management for large scale applications, Evan You, creator of Vue.js, has said that these kind of solutions are suitable for small scale applications, but are not scalable for larger applications.

In most cases, the built-in state management patterns provided by the frameworks themselves are insufficient for large scale apps, and a dedicated solution like Redux or Vuex must be used.

With that in mind, arguing about how state is managed in your application is most likely a premature optimization, and, as with most things, it’s a matter of personal preference. Besides, you might not even need to worry about it.

React Native vs. ?

One area where React clearly has an advantage is the ability to create native mobile applications with React Native. The ability to use JavaScript, CSS and HTML to create legitimate native mobile apps is a game changer. The Vue community and e-commerce giant the Alibaba Group are working to create Vue’s version of React Native called Weex, but it’s still in development and clearly not as battle-tested.

So who wins the battle?

TLDR; JavaScript sux, use TypeScript

If you’re in the market for a shiny new JavaScript UI framework, you can’t go wrong with either React or Vue. While React seems to be more popular, Vue is gaining popularity and isn’t going anywhere. If you’re looking to integrate a new JavaScript framework into an existing codebase, I’d give Vue a look. If you’re looking to build a mobile app with web technologies, React (for now) is the clear winner. In reality, either is a fine choice for building a modern JavaScript app and it really depends on which approach is more appealing to you.

What are your thoughts on Vue and/or React? Let us know if the comments!

Since this article published a LOT has happened in the React world. Matt Mullenweg announced that Gutenberg and Calypso would be dropping React because of the patents clause, then Facebook changed the React license to drop the patents clause, then everone showed up for the weekly WordPress core JavaScript meeting to discuss JS things and THEN React 16 was released. Where does that leave things with React, Vue and WordPress? Well, I’m not sure. It’s all still up in the air from a WordPress perspective. We’re working on a follow-up to this post and want to know: do you think this changes anything in regards to React vs Vue?

About the Author

Peter Tasker

Peter is a PHP and JavaScript developer from Ottawa, Ontario, Canada. In a previous life he worked for marketing and public relations agencies. Loves WordPress, dislikes FTP.

  • gatchaman

    Vue is so much better for integrating into an existing WordPress site. React is a bit of overkill for most of my projects.

    • Peter Tasker

      Just curious, what makes it better for you? I think in terms of what WP core uses it’s a bit different as they’re talking about adding Webpack in place of Grunt. Is React overkill for WordPress core?

      • gatchaman

        I was doing pretty standard stuff. The sort of thing I used jQuery for in the past (basic retrieval from the server via $get, displaying and interacting with returned data, etc.). Vue made it much simpler than jQuery. But the amount of work required didn’t call for anything like Webpack. Simple Gulp builds of script files was enough alone.

        I think some of the documentation with Vue (and React and Angular for that matter) overcomplicate things. I seldom work on single page apps, and don’t need every project to act like one.

        • Peter Tasker

          Yeah, as I mentioned above you don’t need Webpack to use Vue so that is a strong selling point if you’re integrating a library into an existing project.

          • Michael Thiessen

            React doesn’t require Webpack or any fancy build steps either. You can simply include the library in a script tag, and use React.createElement. JSX is just syntactic sugar on top to make it easier to read and write.

    • NgM

      The amount of misinformation in the comments here is amazing.

      Vue isn’t “so much better for integrating into an existing WordPress site.”

      Both React and Vue are equally easy to integrate into WordPress.

  • I’m just waiting for more-educated WordPress contributors to make their choice. Whatever they choose is what I’m going to go with.

    I have been reluctant to learn a modern JS framework because the network has felt too volatile for me to make a jump, and I really don’t see a point in learning something until I decide to use it in my daily workflow. I invest my time in getting really good at the tools I use instead of pretty good at a bunch of different tools.

    Once the community makes this decision, I have a solid reason to learn one of these frameworks. Until then, I’ll just stick with jQuery, even though I dislike it.

    • Nocare

      Responsible use of jQuery and WordPress itself is plenty. Too often I see people go off the deep end with front end frameworks and get nothing useful done in a timely manner.

      On smaller scale sites the biggest performance hits are going to come from bad or bottlenecked in code. A framework can’t really fix that as stupid/lazy always finds a way.

      There is a new hot framework and 5k “vs” blog posts every 6 months anyway. Over engineering sells well right now I guess.

      • That’s kind of where I’m at most of the time. I don’t need much more than a few quick jQuery manipulations for most of what I do, but every once in a while I do.

    • Peter Tasker

      Sounds like at WCEU a decision was made, so I’m guessing the announcement will be out soon.

    • JamesDiGioia

      The counter to this is that a number of the frameworks share concepts that are broadly applicable. Understanding what a component is applies to React, Vue, Angular and others. The knowledge transfers, even if the specific implementations are different between them, so there isn’t a reason to avoid learning one. Understanding React makes learning Vue easier, and gives you a better sense of what trade-offs are made when choosing one over the other.

      Also, many of these frameworks follow a similar Flux-y pattern (actions up, data down), which is additional knowledge that again transfers regardless of framework. The volatility in the JS community has settled down since a few years ago, and these concepts are broadly applicable, so I’d highly recommend picking one (usually React) and learning it as much for its concepts/approaches as its specific implementation.

      • You’re certainly not the first person to counter with that :), and your points are valid.

  • boydbme

    Getting on a plane tonight to head out to Poland for VueConf 2017. I’d be absolutely stoked if Vue was encouraged as a default in WordPress setups. We’ve already completed a few projects where the front-end was a Vue app talking to a headless WordPress install via the JSON api. Combines the best of reactive front-ends with an easy dashboard for clients to manage data.

  • Matt

    If WordPress.org wants to increase the number of developers that can quickly get up to speed with core contributions, theme and plugin development, etc they should choose Vue. Doing otherwise seems like it’s just creating an unnecessary barrier to entry.

    As they’re already familiar with React, they may be blind to the negative ramifications of using it over Vue if there’s any significant bias already present. I must give them credit though for putting the choices out there even if choice itself is an illusion in the end.

    • Peter Tasker

      I think the decision on which framework to use in WordPress core is really the only decision being made. You don’t have to use Vue/React in your own themes and plugins. Those are still open. Does anyone use Backbone in their themes/plugins?

      But I do agree that adding whichever framework will increase the barrier for entry, and I think one of the things the core-js team is planning on doing is increasing the documentation and quick starts. Something I’m planning to contribute to as well!

      What kind of negative ramifications do you think there’ll be by choosing React?

  • JamesDiGioia

    Be careful with code that dynamically add keys to objects in Vue:

    “`
    if (!this.orders.hasOwnProperty(key)) {
    this.orders[key] = {count:0};
    }
    “`

    This actually won’t get tracked properly by Vue’s reactivity system. Vue bootstrap’s the component’s data and registers getters & setters on all of the properties currently on the object. Because this is adding a new key to the object, it’s not tracked by default. In order to make sure it gets tracked, add it like this:

    “`
    if (!this.orders.hasOwnProperty(key)) {
    this.$set(this.orders, key, {count:0});
    }
    “`

    • Peter Tasker

      Good catch @JamesDiGioia:disqus! Being a newbie to Vue I assumed that since the top level object key was already attached to the Vue object, nested objects would also be reactive. For anyone wondering, more info on reactivity can be found in the Vue docs: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

      • JamesDiGioia

        This has messed me up so many times when developing in Vue that it’s really turning me off to their reactivity system, especially coming from Redux where I’m so used to creating new objects. Mutating objects feels foreign and wrong, and mentally tracking whether keys exist on the object is a layer of mental overhead I’m not a fan of.

        • Peter Tasker

          Yep same here. Thinking in React vs Vue is soooo different. Local state objects vs object props does feel a bit backward.

  • Jon

    First, this is an _awesome_ comparison piece, thanks for contributing it!

    I keep reading these and the more I talk to people (all over WCEU) my opinion becomes firmer that Vue is the better choice, but that neither is bad choice. In which case a quick decision is probably better for the project than a slow one.

    Personally, my JS novice brain finds Vue way more accessible and easy to understand as I read it. Vue also seems much easier to integrate with WordPress’ historic methodologies, and it really just makes more sense to me out of the box. As I talk to people it’s clear Vue has a _lot_ of vocal supporters, whereas React has a lot of quiet supporters.

    While the “powers that be” do seam to be sincerely entertaining Vue, it does seem a foregone conclusion it’s going to be React from those “deciders”.

    I haven’t heard many arguments for React beyond “it’s what we know”, “it’s more mature” and “react native is awesome”. None of those seem key to me. Vue is easy to learn, honestly pretty mature on it’s own, and “native” doesn’t really matter to WordPress.

    The thing that bothers me is hearing that the decision core makes isn’t going to affect or limit plugin and theme developers… it absolutely does in a huge way.

    I get that a bunch of important core people already jumped on the React bandwagon (Automatticians, Yoast, Human Made and some others). However, I still feel like _that_ isn’t an important factor. Learning and training is easy compared to deprecating and changing things WP. Decisions should be weighed on what is best for everyone over the next 10 years.

    For every argument there is an equally valid counter argument… Either choice will work out ok, but a quick decision would serve everyone better than this dragging on for months or years like so many key decisions in WP core seem to…

    • Thiago Cangussu

      I don’t know why people keep pretending there is a decision to be made about what libray will be used by WordPress core. Gutenberg have been built with React. They already made the decision. Why would they choose Vue now? Nobody will recode Gutenberg using Vue and load 2 libraries is just insane. So they will keep React.

  • DeryckOE

    Hi Peter, there is broken link on post. There is a missing “i” on https://github.com/vuejs/vue-cl

    Great post, by the way.

    • Peter Tasker

      Right you are! Fixed.

  • Oli101

    I’ve been learning React.js for a few weeks and it’s actually not that hard to pick up. It’s just JavaScript after all so if you take the time to learn JavaScript then you will learn React fairly quickly.
    I’ve never used Vue.js but from what I’ve read Vue is pretty easy to learn.
    I’m not really fussed as to which JS library the WordPress core team decide to use but they need to make a decision soon so we all know which library to invest our time in learning.

    • Peter Tasker

      Yep, I had the same thoughts, I recently learned Vue and had the same feeling as when I learned React a couple years back. Same kind of thing and the documentation in both cases in fantastic.

  • Jon

    I don’t get why people keep saying “developers will still be able to use whatever they want”.

    The WordPress way has always been to use Core APIs whenever possible. If there is a core API that creates a settings/metafields/post editor boxes/etc… then I’m not going to use that AND modify or extend that same page with Vue.

    One would assume at some point the left sidebar in the admin get some SPA style love, so _anything_ wrapped with that chrome will either load both (insane) or be built with what core uses (sane).

    • Jon

      ^ as a plugin dev… but as a theme dev it’s the same thing, I’m not going to build a theme based on Vue and then build the backend in React to match core… it’s going to be all the same.

  • I wonder how do you plan to integrate Vue.js templates into an existing app without a build step since the Vue templates are compiled at build time AFAIK..

  • victor hazbun

    Vue > React, why? Short learning curve, simple to code, great docs, if you are angular (1) developer it’s a big advantage because they are really similar.

    • “if you are angular (1) developer” – hahaha. Truth be told, vue.js has already surpassed react.js in actual use/adaptation because many developers have abandoned angular & jumped to vue.js. With virtually nothing to learn, even developers who have no prior Angular experience can build things quickly on vue.js and the chart below clearly shows this to be true.

      https://w3techs.com/technologies/comparison/js-react,js-vuejs

      react.js is a total mess to maintain. if you need to make just one css change, you can’t just change the css file in react.js.

      Shits about to hit the fan & most ppl, including Automattic, are clueless as to what they’ve got into.

      react.js will increase development & maintenance cost beyond imagination for companies that decide to use it; not sure if that’s a good or bad thing for developers though.

      Lastly, react.js is not open source. FB can shut your project down if FB likes it & wishes to steal your product. This won’t affect small guys/companies but Automattic doesn’t seem to understand this.

      • victor hazbun

        You man, I like you #nohomo

      • NgM

        The sheer amount of misinformation in this comment is truly “mind bottling.”

        Joking aside, here are the facts:
        -vue.js has not taken over react in actual usage. w3techs is not an authoritative source.
        -React is incredibly easy to maintain. Your CSS example is simply nonsense.
        -Development and Maintenance costs have little to do with React v Vue and more to do with project structure and team leadership.
        -React is open source. FB cannot shut down a project and steal your product.

        While I appreciate candidate debate in the tech community, these types of postings are divisive, inflammatory and add little value to the conversation.

        • Pull pistols or whistle Dixie

          “these types of postings are divisive, inflammatory”

          Spoken like a Google / silicon valley, alt-left, hysterical, mountain out of molehills, snowflake douche….amiright?

          How is this post/opinion inflammatory regardless if the post/opinion is 100% accurate?

          You people need to check yourselves and understand that words have specific meaning — and quit being little drama queens.

  • beck6456

    Every java programmers are like this post and i think it will be great tips for them. To get more better suggestion from here they need to read this kind of article in here regularly.

  • chris marx

    Angular 2/4 does everything mentioned here, I think it’s time to consider it as well

    • Barry Tester

      I came from angularjs to angular 2 – and the pain of constantly changing to accommodate the mercurial nature of the angular dev team as they worked through to version 4. After picking up Vue and migrating the entire project in 6 weeks (which included learning Vue) – I won’t use Angular again. It’s too prescriptive and the sheer amount of scaffold required, even with Typescript (which I miss a little bit) just makes it not worth the pain and effort

      • chris marx

        Where you using the angular cli? Since the cli, there is zero scaffolding-

        • Barry Tester

          Yeah I used that. It probably would’ve been better if I’d had it set up for single-file components, rather than it crapping out 4 files for each component – the project folder was huge.
          Maybe I’ll take another look at Angular when I’ve a large enterprise project and Angular is stable, as I was at the bleeding edge – the C# devs I mentored really liked Typescript… but for me, .vue single-file templates with pug instead of HTML is awesome – I’m trying to write as little code as possible, and this makes me super-productive 🙂

  • Sadegh hp

    what about aurelia ?