The VueJS vs React battle will be a headliner for a long time. VueJS is competing against React to ascend to the throne as the best JavaScript library for frontend web development. But Vue is still struggling to reach React’s level of popularity in 2020.

Given the popularity of these libraries, the outcome of React vs Vue match seems obvious. React is a safer choice than Vue for developing single-page apps. We may prefer React over other frameworks thanks to its solid ecosystem. But if we’re to choose between React and Vue, then we must consider their respective ecosystems. Can Vue match what React offers in terms of ecosystem? Spoiler alert: yes, Vue does have enough guns in its arsenal.

React and Vue are very similar. There’s no React framework and there’s no Vue framework. Both tools are JavaScript libraries for creating the view part of our apps. But we can quite easily build a framework around React and Vue using many ready tools from their respective ecosystems. We’ll explain what tools you can use with Vue that are comparable to those for React.

We’ll review the following components of the React and Vue ecosystems:

Ready build tools for quicker project setup

Component-based architectures

Routing with vue-router and react-router

State management with Flux and Vuex

Building AJAX requests

So let’s set off in quest of the most convenient JS library for single-page app development.

Build Tools for Vue- and React-Based Apps

A long time ago, to build an app on the client side we only needed an index.html file with a styles.css file. Then we linked up the jQuery library to index.html to work on the functionality. With React and Vue libraries, we can insert links to these libraries in the project’s index.html file and build our apps just like with jQuery. But React or Vue alone isn’t enough to develop a modern single-page application.

Because browsers don’t yet support all features of modern JavaScript (the EcmaScript 6 specification), and because we need to test our apps as well as develop various complex parts for our apps, we must pick plenty of tools for each project before we even start developing it. React and Vue ecosystems have special tools that simplify our life a lot in terms of building development environment for React- and Vue-based projects.

Create React App - a Command Line Interface for React

What’s great about React is that we can use a pre-configured setup for our React-based projects.

There’s an official React command line interface (CLI) called Create React App. After installing Create React App, we simply run the “create-react-app” command from the terminal. We also pass this command a project name and thus create a new build environment. The “create-react-app” command installs and configures Webpack and Babel as well as many other dependencies that all will be hidden in the NPM modules directory.

React’s command line interface also offers several additional commands:

Thanks to Create React App, we can start developing our React-based applications right away, which is a very pleasant experience.

Vue-cli - a Command Line Interface for VueJS

Can Vue beat Create React App with its own solution? We can use vue-cli, a command line interface tool for building Vue-based projects.

In short, vue-cli proves as advanced a solution as Create React App. With vue-cli, we can create an environment with several possible options:

A full setup with either Webpack or Browserify for managing app modules; besides Webpack or Browserify, we also get other important libraries for hot reloading and code linting, as well as a couple of frameworks for testing.

A simple setup, which includes only Webpack and vue-loader or Browserify with vueify.

If you need, vue-cli can also install vue-router for routing and vue-resource for making AJAX requests. We’ll talk about these parts of the Vue ecosystem in later sections.

Is there any difference between React Create App and vue-cli? The basic difference is that with React Create App, every dependency is hidden in the NPM directory. In other words, the package.json file in a React app will be much cleaner than what you get with vue-cli.

The following package.json file was created by the Create React App. As we can see, there are only a few dependencies:

Create React App actually lets you move all the dependencies from the NPM folder back to the package.json file. If you want to change a dependency, Create React App lets you do so: just use the “npm run eject” command.

If you create a full Webpack package with vue-cli, you’ll get the following package.json file:

You’ll get this immense version of package.json based on a full Webpack installation. But vue-cli is flexible: you can also choose from four project templates. It’s possible to create a fully custom template with the libraries you like most. And you can use this template for any future Vue-based projects.

The React and Vue command line interfaces will equip most developers with all necessary tools right away. React Create App is a bit cleaner of a way to create a project, as the package.json file doesn’t get cluttered with dozens of dependencies. But we’d say that Vue offers marginally more flexibility as we can build our own project templates.

The View Part of React and Vue

Once we’ve built a project environment for a React or Vue app, we’re ready to start building basic components. Essentially, Vue and React adhere to the same approach: everything that belongs to a component is crammed in one file.

In React, a component file contains all the logic plus the template. For VueJS components, files contain all the logic, the template, and component-related styles. A very simple React component looks like this:

With JSX syntax, we simply mix JavaScript and HTML. We interpolate values from JavaScript into the layout using curly braces and use data from the state object in our template. The state object stores component-specific data. For communication between React components, we use props – an object that we pass from parent to child components. “this.props.list” is an example of a props object.

Since Vue borrows concepts from React, it’s not surprising that VueJS components look similar to React components to a certain extent. Vue components are divided into three parts. On top, you’ll find the HTML markup with interpolated values from JavaScript. Below the markup, there’s the script tag that contains all the logic and component-related data. Finally, CSS is also written in the component file:

As we can see, Vue provides directives (v-model for forms) to bind templates with component data and to listen to various events. If you’re familiar with Angular, you’ll immediately get used to Vue’s approach to binding templates and components. React, on the other hand, wants you to write a bit more code to bind values in components with values in templates.

As for communication between components, Vue can pass data from a parent component to a child component with a props object, just as React does.

Next, while keeping styles in a component’s file in Vue, we can easily scope styles to this component using a special attribute, “scoped.” Having styles in the same file along with the template and component logic is an advantage and disadvantage at the same time:

Advantage: We can use short names for classes.

Advantage: Classes are fully isolated thanks to the scoped feature; no conflicts with other classes.

Disadvantage: It’s more difficult to search styles by class names in Vue-based projects.

As you might know, you can write inline styles in React components, but using inline styles isn’t the best approach when building React-based apps. Instead, you can benefit from a plethora of solutions to manage styles for React components.

What can we deduce from the Vue vs React comparison in terms of building app components? Both libraries let us structure components and pass data around in a similar fashion. At the same time we reckon Vue templates simpler than React templates. For example, using directives to pass values from a component to its template is definitely cleaner than writing complex logic (e.g. if statements) in JSX language.

As for managing styles, Vue again makes it simpler, as you can write styles in the same file as logic and markup. With React, you have to use additional libraries.

Routing with VueJS and React

Only when you implement routing do you actually transform your app into a true single-page application. With properly implemented routing, we can do many thing for our apps such as:

Route to different pages of our app without reloading

Manage routing to child components

More efficiently use the HTML5 history API

Implement lazy loading (when a component doesn’t load until we actually go to its page)

These are only a bare minimum of what a modern router must do. To deliver these bare minimum features – and more – React benefits from a dedicated library called react-router. Vue doesn’t trail behind, and uses its own library with a similar name, vue-router.

When using react-router and vue-router, we should render the router in the main.js file of our project. We should pass app components to their respective routes in this file.

React-router uses Router, Route, IndexRoute, and hashHistory (for HTML5 history) to implement routes. For a React-based app we’ll usually put router in the main.js file. Vue, however, wants to make our apps more modular. With Vue, a separate file is often created to accommodate all router-related code:

In terms of how the router is implemented (stored in a separate file), Vue mimics Angular rather than React.

With Vue, you’ll have to insert special HTML tags into layouts to link to components. To specify where to render components, you’ll use the router-view tag. To provide links to those components in the navigation bar, you’ll use the router-link tag. React, in turn, uses the power of JSX syntax: custom IndexLink and Link tags route to specified components.

As for lazy loading, Vue copies React’s approach, using asynchronous components and a Webpack feature called code splitting for lazy loading. For example, here’s how React employs lazy loading:

And this is how the Vue router looks when powered with lazy loading:

The “resolve => require(['@/components/HomeScreen'], resolve)” part is what lets us load a Vue component only when necessary.

In conclusion, we can’t say that vue-router is better than react-router or vice versa. Vue, in terms of routing, is comparable with React, and you’ll get all the features you need with either router.

Managing State in React- and Vue-Based Apps

We’ve already touched upon state management in the previous section on creating basic components. For a quick recap, both Vue and React implement a concept of state to store app data. A state object contains a component-level application state. Then there’s a props object that we can use to pass data from parent components to child components. Props objects are also available in both React and Vue. Lastly, React and Vue components use event handlers to notify other components about changes.

The problem with using these state, props, and event handlers is that they aren’t really efficient at handling data flow. To fill the state handler gap for React, Facebook presented Flux. Flux takes care of the entire data flow in React applications.

Let us recall what the Flux architecture looks like:

As we can see, Flux consists of four basic components: store, actions, dispatcher, and views. Flux implements the famous one-way data flow: React components create actions that are delivered by the dispatcher to all stores. And when any store gets updated, the change is also reflected in its components.

Why are we talking about Flux for the thousandth time? Because Flux has inspired many other libraries for state management, including Vuex, a state management library tailored for Vue.

Let’s now take a look at the diagram that represents the building blocks of Vuex:

What we see is that Vuex copies the one-way data flow approach and provides building blocks for Vue similar to those that Flux provides for React. Vuex adds some quirks, though:

A Vuex store, just like a Flux store, contains the entire state of your application, plus mutations, actions, and getters. In the example above, you can view only state and mutations, which are just an object and a JavaScript function respectively. Vuex actions are often described in a separate file. Actions basically run mutations: one action dispatches one mutation to change the state of the app:

Getters are used in components to obtain data from the store. Vue components simply get necessary parts of the application state through getters and run necessary actions to perform changes in the app. Here’s a more detailed perspective on how Vuex works.

The bottom line is that Vuex and Flux are similar in terms of the concept: both implement the one-way data flow to keep the complexity of your app low. Moving from React+Flux to Vue+Vuex won’t be an issue.

Connect Vue and React to the Backend

Communication with the backend is another vital part of single-page applications. Although most calculations are performed on the client side (in a browser), your Vue or React-based app must still communicate with a backend to retrieve static data. Therefore, the React and Vue ecosystems must offer HTTP libraries. And there are actually plenty of solutions for both JavaScript libraries, as we will discuss.

React enables us to build simple AJAX requests for communication with the backend. But whenever we need to write more advanced requests, we can use dedicated libraries or middleware. Many libraries for making asynchronous API calls with React are actually based on Redux (a Flux-inspired JS library for state management): redux-thunk and redux-promise are the most prominent examples. Axios is another HTTP library often used with React. In short, React can be coupled with many solutions. It’s only our job to determine what we should use for our React apps.

As Vue mimics React in this regard as well, we can also employ several libraries for asynchronously calling APIs with Vue. It’s worth mentioning the two most-used HTTP libraries for Vue apps. One is vue-resource, which was an official HTTP library for Vue: Vue supporters decided to remove vue-resource from Vue’s hard dependencies. Besides vue-resource, you can also pair the already mentioned Axios with your Vue-based app. Axios is actually the suggested replacement for vue-resource by the creators of Vue.

What we want to highlight by listing all these libraries is that React and Vue don’t use any built-in solutions for handling AJAX requests. Instead, we can switch to any HTTP library we need to get the job done no matter whether we’re using React or Vue for our apps. In other words, VueJS is again on par with React.

React vs Vue: Who’s Winning?

There’s no clear winner in the battle between React and Vue. The outcome of this struggle depends on what you think is the better solution. Still, we can deduce that:

React is slightly more difficult to learn than Vue. One reason for React being more difficult is JSX.

React has a very powerful ecosystem, but Vue offers everything an SPA is built from.

We intentionally didn’t talk about VueJS performance compared to React performance. In real world applications, there’s no substantial difference. If you want the maximum speed, then you should use pure JavaScript (or WebAssembly when it comes out).

Although Vue is simpler than React in some regards, this doesn’t necessarily mean you have to jump to Vue. Vue is a newer technology, and it’ll take time for the Vue ecosystem to reach the React ecosystem’s scale (if it ever does). Besides, if you already know React, there’s no real reason to switch to Vue unless you simply like to learn new things or your web development team decides to use Vue for a project.