I have been a full-time React.js developer for 3 years and a Vue.js developer for 3 months. Here are the issues I have with Vue.js, and why I will stick with React.js for future projects.
TLDR:
- Vue.js mutates data, a lot
- Vue.js needlessly uses custom syntax, rather than vanilla JS
- Vue.js has poor IDE support. I.e, WebStorm didn't get full support until very recently.
- Poor TypeScript support (especially inside the templates)
- Lots of implicit behavior
- Lots of function overloading
The anti-patterns are considered features
It's interesting how the best practices for Vue.js and React.js are the opposites of each other in so many cases.
As far as watchers, it's a React best practice to have several smaller, rather than one big. (official doc, LogRocket post).
Similarly, React recommends to not use contexts (provide/inject in vue) unless absolutely necessary.
Additionally, it's an anti-pattern to have useMemo everywhere (computed in Vue) (LogRocket, Bitsrc, Kevin Van Ryckegem).
It's also inadvisable to blindly pass all props from parent to child, where as Vue has first class support for fallthrough props.
And the whole SFC (single-file component) concept is an anti-pattern. There is an ESLint rule for react that restricts files to a single component, but that is considered a bad practice by most.
The fact that SFC requires default imports rather than named imports is bad too. (A short article from Lloyd Atknson, Another great article from Kris Kaczor, TypeScript Deep Dive).
The custom syntax
10 years ago, when Vue.js was getting started, JavaScript was way more limited that in it today. There was no lambda functions, no map/filter and no const. I know, those were the dark times.
Given that, Vue.js team did what seemed at the time like a good idea and created their own syntax for templates.
Unfortunately, there are large negative consequences:
- Your favorite IDE might not support Vue.js syntax. That can mean anything from broken syntax, to no inline TypeScript suggestions.
- Formatters/Linters and Minifierrs don't work out of the box unless they support this syntax.
- You have to learn yet another way of doing the same thing. You have to waste time learning yet another syntax for looping (v-for) rather than using a more familiar
.map()
. - Additional build steps are required.
Given these negatives, I would have expected Vue.js team to shift their users to native JS and JSX in version 3, but was shocked to find out they are still discouraging usage of JSX in favor of SFC (somehow, Vue.js manages to struggle with optimizing JSX more than with a template string).
Data Mutation
After more than 50 years of developing software, most have finally agreed that data mutation should be minimized as it has some large negative side effects (pun intended). Code with mutation is more likely to contain bugs, is harder to test, harder to debug and harder to reuse.
See and an excellent article from Artem Sapegin a post from Islam Farg to find out more.
Now, what if I mention that React.js avoids mutation like a plague, where that's what you do all the time in Vue.js?
The compositions API (copied from React.js) is a small step in a right direction, but too little too late.
An ocean full of implicit behavior and function overloading
Similarly to data mutation, implicit behavior is discouraged if you want a chance at writing readable and maintainable code. It's okay to abstract away complexity, but not at the cost of bugs.
- Vue.js tracks the dependencies of computed properties implicitly - great for writing less code, bad for controlling your code, explicitly seeing what the behaviour is and avoiding bugs (i.e, conditionals in computed could lead to data that is not properly updated).
- There is half a dozen overloads for
watch()
alone. In comparison to React's no overloads for useEffect - a single signature to rule them all (besides the weird no-dependencies case that should be avoided). - Syntax for v-bind, v-for and v-on has a lot of variations.
Top comments (13)
Update from 2024:
The tooling support is still bad. e.g. github.com/prettier/prettier-vscod... (and that's the most popular formatter out there!)
Vue Vine is nice - tries to fix some issues with SFC, though the community called it "Sacrilegious" ๐คฃ reddit.com/r/vuejs/comments/1cyinn...
Seems like the author have no idea how to use Vue, neither has understanding of it.
Good luck with controlling your code with all "beauties" react offers you to control the code๐๐๐
Thank you for the comment. I must say in 3 months of using Vue I didn't have time to get sufficient experience with it. Could you please enumerate some of the big things I am missing?
Before we dive in, may I ask you how in a 3 month of using Vue you have found all these flaws?
Vue's performance is pretty the same as of react but offers numerous advantages
You were right saying that react exposes the control to the developer, but this is not necessarily the good thing as it opens a gate for bugs and is pretty unclear how to structure your code.
After having worked with both react and Vue in production grade applications, I would go 100% Vue for any new project I have to choose between the two.
Again, all these are my personal opinion based on projects I have worked on. In any case, before you write a post of how bad the tool is, gain experience working with it to understand it better and then compare it with other solutions available.
Good luck in learning and exploring ๐๐
From all the tests I have seen, Vue is a bit faster than React.
I, along with many much more experienced developers don't agree with this. Single component per file restriction is not streamlining anything (making it harder to create components dynamically and to reuse code). Plus every config variable has to be globally exported if you want to use it between two components. And default exports is an anti-pattern (see cited sources in my article).
Are you talking about the Vue Router? That's a separate library. I didn't want to pollute this discussion by introducting libraries (i.e, React Router) and wanted to focus on just the core framework. But if you want to compare libraries, React has many times more solutions than Vue has to offer because of the much larger community.
Can say the same thing for React - in fact more because of a much larger community and many more packages being available (3 times more according to a quick npmjs search)
Once again, the feature that React has without introducing custom syntax. I.e, the dynamic slot names (vuejs.org/guide/components/slots.h...) - why do I have to remember this syntax when JS has native syntax for dynamic key names?
But far my biggest problem with Vue's slots is that they are not type safe (most notably Scoped Slots), unlike in React. I might be missing something, but is there really no way to enfoce type safety for slot props and to type-safely read these props?
Thank you! Also, thank you for responding to the article and continuing the civil debate.
Civil debate is the way :)
Performance
You will not see difference between the two. User will not see the difference. Speed is redundant here.
Single file components
If you and many other developers do not think it is a good thing, it does not mean that it is bad. SFC are battle tested in production and reduce time of dealing with separate files significantly.
Config variable? The same applies to React.
Router
Let's put it aside. You are missing the point when you write that react has many more to offer. Number of packages is not the factor here. It is about how well the router plays together with the view.
Slots
Perhaps in term of types it is not perfect, but offers an elegant way to compose and manage complicated layouts with ease.
I get a light feeling that your experience with Vue might be lacking in order to understand and compare the two solutions. Try building a midsize/large app with both and then try to analyse which tool has which advantages/disadvantages.
Recently I have completed a midsize app with React and had an opportunity to compare the two. From my perspective, Vue offers better DX and less effort to develop.
Again, to each his own. This was my 5 cents.
Take care ๐
A per webstorm support - webstorm supports Vue for a long time and it's getting better and better. Had not have any troubles here.
The problem now is using Vue inside astro.js and astro.js support in jetbrains products.
WebStorm/PyCharm didn't gain TypeScript support until 3 years after the Vue 3 release (blog.jetbrains.com/webstorm/2023/0...).
Without TypeScript, I don't think Vue or React or any other framework is usable in production.
fyi vs code is opensource and widely used development tool and it has volar extensions officially by vue community which give you very classy experience for vue development.
Each framework has its own internal definition and hence if you see react it has className for css classes its not even cleaner then Vue templates which uses regular html css
Vue 3.x has good typescript support.
And i feel vue js has better seperation of concern which make easy to learn and get started
Yes, VS Code support for Vue has been great
My main complaint was with other popular IDEs.
Most notably, WebStorm/PyCharm didn't gain TypeScript support until 3 years after the Vue 3 release - I don't know why that's accepted by the Vue community (blog.jetbrains.com/webstorm/2023/0...)
I mean stick to your framework that allows you to infinite loop easy.
Provide/inject is not meant to be used much, use pinia
Thank you for the comment. I must say the official doc on provide/inject does not mention pinia at all. In this article I was only evaluating the native capabilities that both frameworks provide, so that the comparison is more apples to apples rather than apples to oranges. I.e, I didn't bring redux into the conversation.
In React, I never felt like I was forced to use another external library as native hooks API felt powerful enough
Vue composition API is pretty much the same thing as react hooks.