- The Vue Instance
- Template Syntax
- Computed Properties and Watchers
- Class and Style Bindings
- Conditional Rendering
- List Rendering
- Event Handling
- Form Input Bindings
- Transition Effects
- Transitioning State
- Render Functions
- Reactivity in Depth
- Custom Directives
- Single File Components
- Deploying For Production
- State Management
- Unit Testing
- Server-Side Rendering
- Migration from Vue 1.x
- Migration from Vue Router 0.7.x
- Migration from Vuex 0.6.x to 1.0
- Comparison with Other Frameworks
- Join the Vue.js Community!
Comparison with Other Frameworks
This is definitely the most difficult page in the guide to write, but we do feel it’s important. Odds are, you’ve had problems you tried to solve and you’ve used another library to solve them. You’re here because you want to know if Vue can solve your specific problems better. That’s what we hope to answer for you.
We also try very hard to avoid bias. As the core team, we obviously like Vue a lot. There are some problems we think it solves better than anything else out there. If we didn’t believe that, we wouldn’t be working on it. We do want to be fair and accurate though. Where other libraries offer significant advantages, such as React’s vast ecosystem of alternative renderers or Knockout’s browser support back to IE6, we try to list these as well.
React and Vue share many similarities. They 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
Being so similar in scope, we’ve put more time into fine-tuning this comparison than any other. We want to ensure not only technical accuracy, but also balance. We point out where React outshines Vue, for example in the richness of their ecosystem and abundance of their custom renderers.
The React community has been instrumental in helping us achieve this balance, with special thanks to Dan Abramov from the React team. He was extremely generous with his time and considerable expertise to help us refine this document until we were both happy with the final result.
With that said, we hope you can feel confident in the fairness of the review below as we explore the differences between these two libraries.
In every real-world scenario that we’ve tested so far, Vue outperforms React by a fair margin. If your eyebrows are raising right now, read further. We’ll breakdown why (and even include a benchmark developed in collaboration with the React team).
When rendering UI, manipulating the DOM is typically the most expensive operation and unfortunately, no library can make those raw operations faster. The best we can do is:
- Minimize the number of necessary DOM mutations. Both React and Vue use virtual DOM abstractions to accomplish this and both implementations work about equally well.
- Add as little overhead as possible on top of those DOM manipulations. This is an area where Vue and React differ.
In React, let’s say the additional overhead of rendering an element is 1 and the overhead of an average component is 2. In Vue, the overhead of an element would be more like 0.1, but the overhead of an average component would be 4, due to the setup required for our reactivity system.
This means that in typical applications, where there are many more elements than components being rendered, Vue will outperform React by a significant margin. In extreme cases however, such as using 1 normal component to render each element, Vue will usually be slower. This isn’t the end of the story though.
If you’re feeling lazy though, below are the numbers from one run in Chrome 52 on a 2014 MacBook Air. To avoid cherry-picking, both benchmarks were actually run 20 separate times, with results from the best runs included below:
In React, you need to implement
shouldComponentUpdate everywhere and use immutable data structures to achieve fully optimized re-renders. In Vue, a component’s dependencies are automatically tracked so that it only updates when one of those dependencies change. The only further optimization that sometimes can be helpful in Vue is adding a
key attribute to items in long lists.
This means updates in unoptimized Vue will be much faster than unoptimized React and actually, due to the improved render performance in Vue, even fully-optimized React will usually be slower than Vue is out-of-the-box.
Obviously, performance in production is the most important and that’s what we’ve been discussing so far. Performance in development still matters though. The good news is that both Vue and React remain fast enough in development for most normal applications.
However, if you’re prototyping any high-performance data visualizations or animations, you may find it useful to know that in scenarios where Vue can’t handle more than 10 frames per second in development, we’ve seen React slow down to about 1 frame per second.
This is due to React’s many heavy invariant checks, which help it to provide many excellent warnings and error messages. We agree that these are important in Vue, but have tried to keep a closer eye on performance while we implement these checks.
Render functions with JSX have a few advantages:
- The tooling support (e.g. linting, type checking, editor autocompletion) for JSX is in some ways more advanced than what’s currently available for Vue templates.
Instead, we offer templates as a simpler alternative:
A few advantages here:
- Many fewer implementation and stylistic decisions have to be made while writing a template
- A template will always be declarative
- Any valid HTML is valid in a template
- It reads more like English (e.g. for each item in items)
This is not only much easier for the developer that’s writing it, but designers and less experienced developers will also find it much easier parsing and contributing code.
The React ecosystem also has a project that allows you to write templates, but there are a few disadvantages:
- It’s not nearly as feature-rich as Vue’s templating system
- It requires separating your HTML from component files
- Because it’s a 3rd party library rather than officially supported, it may or may not be kept up-to-date with React core into the future
Unless you spread components out over multiple files (for example with CSS Modules), scoping CSS in React comes with caveats. Very basic CSS works great out-of-the-box, but some more complex features such as hover states, media queries, and pseudo-selectors all either require heavy dependencies to reinvent what CSS already does - or they simply don’t work.
Vue on the other hand, gives you full access to CSS within single-file components:
scoped attribute automatically scopes this CSS to your component by adding a unique attribute (such as
data-v-1) to elements and compiling
.list-container:hover to something like
For large applications, both Vue and React offer robust routing solutions. The React community has also been very innovative in terms of state management solutions (e.g. Flux/Redux). These state management patterns and even Redux itself can be easily integrated into Vue applications. In fact, Vue has even taken this model a step further with Vuex, an Elm-inspired state management solution that integrates deeply into Vue that we think offers a superior development experience.
Another important difference between these offerings is that 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.
Finally, Vue offers a CLI project generator that makes it trivially easy to start a new project using your choice of build system, including Webpack, Browserify, or even no build system. React is also making strides in this area with create-react-app, but it currently has a few limitations:
- It does not allow any configuration during project generation, while Vue’s project templates allow Yeoman-like customization.
- It only offers a single template that assumes you’re building a single-page application, while Vue offers a wide variety of templates for various purposes and build systems.
- It cannot generate projects from user-built templates, which can be especially useful for enterprise environments with pre-established conventions.
It’s important to note though that many of these limitations are intentional design decisions made by the create-react-app team and they do have their advantages. For example, as long your project’s needs are very simple and you never need to “eject” to customize your build process, you’ll be able to update it as a dependency. You can read more about the differing philosophy here.
React is renowned for its steep learning curve. Before you can really get started, you need to know about JSX and probably ES2015+, since many examples use React’s class syntax. You also have to learn about build systems, because although you could technically use Babel Standalone to live-compile your code, it’s not recommended for production.
While Vue scales up just as well as, if not better than React, it also scales down just as well as jQuery. That’s right - all you have to do is drop a single script tag into a page:
Then you can start writing Vue code and even ship the minified version to production without feeling guilty or having to worry about performance problems.
Since you don’t need to know about JSX, ES2015, or build systems to get started with Vue, it also typically takes developers less than a day reading the guide to learn enough to build non-trivial applications.
At this moment, Weex is still in active development and is not as mature and battle-tested as ReactNative, but its development is driven by the production needs of the largest e-commerce business in the world, and the Vue team will also actively collaborate with the Weex team to ensure a smooth experience for Vue developers.
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.
Some of Vue’s syntax will look very similar to Angular (e.g.
ng-if). This is because there were a lot of things that Angular got right and these were an inspiration for Vue very early in its development. There are also many pains that come with Angular however, where Vue has attempted to offer a significant improvement.
Vue is much simpler than Angular 1, both in terms of API and design. Learning enough to build non-trivial applications typically takes less than a day, which is not true for Angular 1.
Angular 1 has strong opinions about how your applications should be structured, while Vue is a more flexible, modular solution. While this makes Vue more adaptable to a wide variety of projects, we also recognize that sometimes it’s useful to have some decisions made for you, so that you can just get started coding.
That’s why we offer a Webpack template that can set you up within minutes, while also granting you access to advanced features such as hot module reloading, linting, CSS extraction, and much more.
Angular 1 uses two-way binding between scopes, while Vue enforces a one-way data flow between components. This makes the flow of data easier to reason about in non-trivial applications.
Vue has a clearer separation between directives and components. Directives are meant to encapsulate DOM manipulations only, while components are self-contained units that have their own view and data logic. In Angular, there’s a lot of confusion between the two.
Vue has better performance and is much, much easier to optimize because it doesn’t use dirty checking. Angular 1 becomes slow when there are a lot of watchers, because every time anything in the scope changes, all these watchers need to be re-evaluated again. Also, the digest cycle may have to run multiple times to “stabilize” if some watcher triggers another update. Angular users often have to resort to esoteric techniques to get around the digest cycle, and in some situations, there’s simply no way to optimize a scope with many watchers.
Vue doesn’t suffer from this at all because it uses a transparent dependency-tracking observation system with async queueing - all changes trigger independently unless they have explicit dependency relationships.
Interestingly, there are quite a few similarities in how Angular 2 and Vue are addressing these Angular 1 issues.
We have a separate section for Angular 2 because it really is a completely new framework. For example, it features a first-class component system, many implementation details have been completely rewritten, and the API has also changed quite drastically.
While Angular 1 could be used for smaller applications, Angular 2 has shifted focus to best facilitate large enterprise applications. As part of this, it almost requires TypeScript, which can be very useful for developers that desire the type safety of languages such as Java and C#.
In terms of performance, both frameworks are exceptionally fast and there isn’t enough data from real world use cases to make a verdict. However if you are determined to see some numbers, Vue 2.0 seems to be ahead of Angular 2 according to this 3rd party benchmark.
Size wise, although Angular 2 with offline compilation and tree-shaking is able to get its size down considerably, a full-featured Vue 2.0 with compiler included (23kb) is still lighter than a tree-shaken bare-bone example of Angular 2 (50kb). And do note the Angular 2 app’s size is small due to tree-shaking, which removes code for features that you are not using. It will eventually grow back to its actual size as you import and use more features from the framework.
Vue is much less opinionated than Angular 2, offering official support for a variety of build systems, with no restrictions on how you structure your application. Many developers enjoy this freedom, while some prefer having only one Right Way to build any application.
Ember is a full-featured framework that is designed to be highly opinionated. It provides a lot of established conventions and once you are familiar enough with them, it can make you very productive. However, it also means the learning curve is high and flexibility suffers. It’s a trade-off when you try to pick between an opinionated framework and a library with a loosely coupled set of tools that work together. The latter gives you more freedom but also requires you to make more architectural decisions.
Performance-wise, Vue outperforms Ember by a fair margin, even after the latest Glimmer engine update in Ember 2.0. Vue automatically batches updates, while in Ember you need to manually manage run loops in performance-critical situations.
Knockout was a pioneer in the MVVM and dependency tracking spaces and its reactivity system is very similar to Vue’s. Its browser support is also very impressive considering everything it does, with support back to IE6! Vue on the other hand only supports IE9+.
Over time though, Knockout development has slowed and it’s begun to show its age a little. For example, its component system lacks a full set of lifecycle hooks and although it’s a very common use case, the interface for passing children to a component feels a little clunky compared to Vue’s.
There also seem to be philosophical differences in the API design which if you’re curious, can be demonstrated by how each handles the creation of a simple todo list. It’s definitely somewhat subjective, but many consider Vue’s API to be less complex and better structured.
Polymer is yet another Google-sponsored project and in fact was a source of inspiration for Vue as well. Vue’s components can be loosely compared to Polymer’s custom elements and both provide a very similar development style. The biggest difference is that Polymer is built upon the latest Web Components features and requires non-trivial polyfills to work (with degraded performance) in browsers that don’t support those features natively. In contrast, Vue works without any dependencies or polyfills down to IE9.
In Polymer 1.0, the team has also made its data-binding system very limited in order to compensate for the performance. For example, the only expressions supported in Polymer templates are boolean negation and single method calls. Its computed property implementation is also not very flexible.
When deploying to production, Polymer recommends loading everything on-the-fly with HTML Imports, which assumes browsers implementing the spec, and HTTP/2 support on both server and client. This may or may not be feasible depending on your target audience and deployment environment. In cases where this is not desirable, you will have to use a special tool called Vulcanizer to bundle your Polymer elements. On this front, Vue can combine its async component feature with Webpack’s code-splitting feature to easily split out parts of the application bundle to be lazy-loaded. This ensures compatibility with older browsers while retaining great app loading performance.
It is also totally feasible to offer deeper integration between Vue with Web Component specs such as Custom Elements and Shadow DOM style encapsulation - however at this moment we are still waiting for the specs to mature and be widely implemented in all mainstream browsers before making any serious commitments.
Riot 2.0 provides a similar component-based development model (which is called a “tag” in Riot), with a minimal and beautifully designed API. Riot and Vue probably share a lot in design philosophies. However, despite being a bit heavier than Riot, Vue does offer some significant advantages:
- True conditional rendering. Riot renders all if branches and simply shows/hides them.
- A far more powerful router. Riot’s routing API is extremely minimal.
- More mature tooling support. Vue provides official support for Webpack, Browserify, and SystemJS, while Riot relies on community support for build system integration.
- Transition effect system. Riot has none.
- Better performance. Despite advertising use of a virtual DOM, Riot in fact uses dirty checking and thus suffers from the same performance issues as Angular 1.