Why I finally chose React over Vue
By: Bill Wohlers
Tags: React, Web Development, Programming, Vue, Software Development

Over the last decade, single-page application (SPA) frameworks have confirmed their place as the standard for modern web development. React and Vue.js, the two most popular SPA libraries for new projects, have been key players in this web revolution.

From afar, these libraries seem nearly identical in form and function; deciding between the two mainly determines the style of your code, not the quality of your product. Yet you can only pick one for your next project. Which should you choose?

This hot debate has prompted many passionate articles and discussions, yet consensus seems to further elude us with every passing year.

After some years building apps with both libraries, I’ve found that I prefer React. Before I present my reasons, I’ll discuss some commonly cited reasons that did not really influence my decision.

It’s not because React is more popular

React fans often point to the size and maturity of its ecosystem. It’s true: React has more Github repositories and experienced developers, and, related to this, add-ons superior in both quality and quantity.

This means more Stack Overflow questions, tutorials, and examples you can reference, and more NPM packages you can use. But I don’t find this a compelling reason to choose React for two reasons.

First, this gap has been closing as Vue‘s momentum has soared, a trend certain to continue for the foreseeable future.

Second, the gap is not currently, by itself, substantial enough to rule out Vue, which has more than enough official and unofficial libraries to remain strongly competitive.

Vue.js is easier — but not enough that it makes a difference

Vue fans will often cite ease-of-use and a gentler learning curve as their justification. While more subjective, this too is not generally disputed. Vue’s documentation is some of the best that exists. Its templating system is more intuitive than JSX, particularly for beginners, and a clearer separation of view and model code helps newer web developers understand the important principles behind MVC design.

This is a compelling reason for beginners to learn Vue before React. Indeed, this is the order I recommend to programmers with no experience in either.

But React’s steeper learning curve should not deter more seasoned engineers. Once a developer has built a substantial app in both React and Vue, the learning curve does not significantly affect development speed or the quality of the product.

So, if both libraries are so similar, and each has its pros and cons, why do I prefer React?

The answer ultimately lies in JSX, React’s templating system. Whereas Vue uses XML with embedded Javascript, JSX is truly Javascript, only formatted like XML.

React, therefore, is JavaScript all the way down — and this has two important benefits.

1. Better compatibility with TypeScript

To understand the value of Typescript compatibility, we need to review the benefits of having a type system in the first place.

For one, it makes code more readable. This isn’t just beneficial to your teammates — it’s beneficial to future you as you scale the application.

Second, a type system helps you design more robust abstractions. Without one, managing many different modules becomes exponentially more difficult as the number of modules increases. The time lost by statically defining types is easily regained, and then some, by no longer needing to memorize or manually reference types.

A final benefit of TypeScript is its help in quickly catching subtle bugs. Consider the following equality comparison:

const num = 5;

const str = "5";

if (num === str) {

// do something

}

The simplicity of this snippet immediately betrays our mistake: using strict equality to compare a number and a string. But we might imagine how, in a larger system without types, the error might be completely lost on us. If we give our variables types, the IDE will immediately highlight the mistake, potentially saving minutes or even hours of frustration.

All these benefits mean faster development and fewer bugs, improvements that see increasing returns as the complexity of the application grows.

JSX = more types

But how does TypeScript relate to JSX? A library truer to Javascript is also truer to TypeScript. Every part of a JSX element can (and should) be typed: components, props, children, and so on.

One important guideline for Typescript usage is what I call the all-or-nothing principle. Using Typescript for some files and plain JS for others encourages laziness. Likewise, setting types for some variables but using any for others defeats the purpose of having types in the first place.

Thus, for a library to integrate well with Typescript, all of its features must be easily typed. Thanks to JSX, React easily meets this criteria.

Indeed, it is possible to type many of these elements in Vue as well, but the effort required is often greater, and the documentation and Stack Overflow questions more scant.

However, if you’re dead set on using both Vue and Typescript, all hope is not lost. More recently, the Vue team has prioritized improving the library’s Typescript experience—Vue 3, after all, is written in it.

But short of adopting JSX (exceedingly unlikely), Vue cannot match React’s Typescript compatibility.

React’s larger ecosystem does make a difference

There’s another important reason that React works better with TypeScript, and it’s thanks to the larger ecosystem. Because TypeScript is easier to use with JSX, more React projects depend on it than Vue projects; in turn, React libraries and add-ons are more likely to support TypeScript.

Ultimately, this means more of our files can end with .ts instead of .js, a win by the all-or-nothing principle.

What if you have no interest in using TypeScript for your next SPA project? If not for the second important benefit of JSX, I might recommend Vue for its ease-of-use and more rapid prototyping capabilities.

But I would also warn you that skirting a type system is a mistake for any app more complex than a four-function calculator, especially if you plan to scale or expand the app later on.

2. A more functional paradigm

Let’s briefly review what it means for code to be functional and why we usually prefer functional code to procedural.

In math and computer science, a function is an operation that consumes some inputs and returns some output. The best functions are pure and deterministic.

Pure functions have no side effects; they ignore state and care only about the inputs to the function.

Deterministic functions always return the same output given the same inputs.

Writing deterministic and pure functions wherever possible improves code quality for various reasons. These functions are easier to test, simpler to think about, and improve code readability.

Consider a simple contrast between functional and procedural code:

const arr = [4, 5, 6]; // Procedural

for (let i of arr) {

i += 1;

} // Functional equivalent

arr = arr.map(i => i + 1);

We shed off two lines, but more importantly, the second snippet is far more concise and easier to read: we set arr to be the same array, mapped by a function that returns its input plus one.

If you want to read more about the benefits or how-to of functional JavaScript, check out this article.

Why does JSX encourage more functional code? Since JSX is JavaScript, we can treat JSX elements as first-class variables. We can easily demonstrate this by rendering a list of elements:

const arr = [4, 5, 6]; const renderFunction = (n) => {

return <SomeComponent someProp={n} />

} return (

<>

{ arr.map(renderFunction) }

</>

)

But in Vue, this is arguably even simpler with v-for :

<template>

<SomeComponent v-for="n in arr" :someProp="n" />

</template>

...

{

data() {

return {

arr: [4, 5, 6]

}

}

}

But what if we want to pass in not n but the result of some operation on n as the prop to SomeComponent, like formatting it as currency?

In React, the adjustment is minimal:

const arr = [4, 5, 6]; const renderFunction = (n) => {

const formattedText = `$${n.toFixed(2)}`;

return <SomeComponent someProp={formattedText} />

} return (

<>

{ arr.map(renderFunction) }

</>

)

As you can see, we enclose the formatting logic within the renderFunction , ensuring separation of concerns. But in Vue, we must define a method for the entire component:

<template>

<SomeComponent v-for="n in arr" :someProp="n" />

</template>

...

{

data() {

return {

arr: [4, 5, 6]

}

},

methods: {

formatAsMoney(n) {

return `$${n.toFixed(2)}`

}

}

}

(Yes, in both examples, you could write the formatting logic in the template, but consider a far more complex operation).

The difference may appear insignificant, but there are two distinct disadvantages to Vue’s organization. First, it spreads code for one part of the component across the entire file. Second, it’s unclear just from looking at the formatAsMoney method where the method is used or what will happen if it’s changed or removed.

Another important difference between React and Vue is how child components pass data up to parents. In React, the parent component passes a function to the child that the child calls; this pattern demands an advanced understanding of functional JavaScript, but is far more powerful and flexible than Vue’s emit pattern. And because React’s functional pattern is truer to Javascript, it also offers superior TypeScript compatibility.

What does this mean for you?

Deciding what tech to use is not a universally objective matter because software engineering isn’t a hard science with cut-and-dry answers.

You should consider various factors when selecting an SPA framework. The ideas presented here should contribute to your decision alongside any other reasons you might have for or against either Vue or React; these might relate to your programming style, your team’s level of comfort with the libraries, or needs for particular add-on libraries.

I’ll close with some final advice: don’t make an important tech decision without fully understanding your options. Before beginning a large web client, don’t just pick Vue because you’ve always used Vue (a mistake I’ve made many times). Take the time to become proficient at React to understand its strong and weak points. The same goes for those who have always used React.

Whatever you pick, your choice shouldn’t determine the quality of your end product, and it certainly shouldn’t determine the quality of your code.

Sort out your wants and needs as a team, discuss the pros and cons of your options, and reach an agreement that satisfies as much of your team as possible.

And if you’re still stuck after that, then go with React.

More content at plainenglish.io