Gutenberg: A Change of Vue?

If you haven't heard the news already, Matt has decided to move Gutenberg, the new WordPress editor, off of React, over people's reaction to the recent response from Facebook's legal team.

Some parts of Facebook's response seem odd, but I also have no idea what the legal landscape is like for one of the largest most publicly visible companies in the world. I don't think there is malicious intent in React's licensing, but at the same time I think it is a wise decision from Matt to ease growing tension in the WordPress space over the use of React in Gutenberg. Any company, organization, or project that feels wary of taking on the legal uncertainty surrounding React, is a project that would no longer be able to use WordPress; an unfortunate price to pay for using React.

What's next?

It is not clear what will be chosen as the replacement for React, and in many ways I wish React did not need to be replaced, because it is awesome. Vue seems to be the chant ringing through all channels of the WordPress community. I have been meaning to learn Vue. The recent news was the final push. After I finished up my tasks Friday, I jumped straight into Vue. It took me very little time to get Vue running, with Vuex to boot, to create a todo list app. It took about two hours. Vue is great! Magic! I can definitely see why people love it. In many ways Vue is solving the same problems React solves. There are many similarities between Vue and React, but also many differences, and many misconceptions the WordPress community seems to have about that relation.

I did not fully dive into Vue yet, by trying out routing etc., but through a cursory glance, Vue Router seems A LOT better than React Router. However it is important to note that with the way React works, React Router is not a good choice, and instead I would recommend Redux First Router, if you are using Redux. If you are purely using React, godspeed. There are many things I haven't tried out yet in Vue, but I think I have a pretty good grasp of it, and here is my take on its differences with React, and how that could potentially impact Gutenberg and the WordPress ecosystem.

Potential of Vue

Claims about Vue from the WordPress space

1. Vue is easier to learn.

One of the reasons I think Vue is regarded as "easy to learn" is that you can write out UIs with a template syntax similar to HTML and make use of "directives" to accomplish things like conditional rendering, rendering lists, and much more without touching any JavaScript. That is definitely very cool, and could be useful in the WordPress space to help developers ease into front end development using JavaScript.

The template language for Vue is really cool. It is all valid HTML, so you can create a Vue template as HTML, then simply instantiate Vue on the root element. This is really cool and lets you get up and running instantly. Most template languages however, become additional overhead on top of learning a core language, and in the long run are probably not very useful.

All of the templates you create in Vue are transformed into "render functions". This is what I ended up using in my todo list app, as this approach was more familiar to me. From what I can tell in Vue, there are five main ways to create your Vues: html files using vue templates, template strings, .vue files, x-templates, and render functions. All of these break down to just render functions, and you could even write your own template language to compile to these render functions, if you really wanted. Custom compiling is how Vue offers JSX support, same with React.

Here is a quick look at the Vue Syntax vs. Custom Rendering functions.

Vue template syntax, using ES6 template strings: ( the ` ` )

Vue.component( 'my-list', {
  template: `
    <ul v-if="items.length">
      <li v-for="item in items">{{ item.name }}</li>
    </ul>
    <p v-else>No items found.</p>
  `,
  props: [ items ]
} )

and now a custom render function:

Vue.component( 'my-list', {
  render: function ( h ) {
    if ( this.items.length ) {
      return h( 'ul', this.items.map( function ( item ) {
        return h( 'li', item.name )
      } ) )
    } else {
      return h( 'p', 'No items found.' )
    }
  },
  props: [ items ]
} )

The Vue template syntax is more concise, but you can only use a limited set of JavaScript in it. To get flexibility out of the template system, directives like v-if and v-for are used. In the render functions approach, much like React, you can use whatever JavaScript you want. Using JSX in Vue, like React, may provide a more condensed "easy" to read template syntax, that won't limit your use of JavaScript.

Once you start using render functions in Vue you might as well be using React. They are very similar at this point, to the point where it is almost staggering. So why would Vue be "easier to learn" at this point if React was already deemed more difficult. I think the argument is that you get a nice ramp up in Vue, whereas React expects you to make the leap from HTML templating right into JSX, and build processes galore.

The reality though is that you will eventually hit the same wall you would have hit while learning React, so it is hard to argue it is truly "easier" to learn it, because there is honestly much, much more to learn in Vue. In fact, because Vue does so much more than React, I would argue Vue is more difficult to learn, because you have so many more options on how you want to configure your use of Vue. React: you learn once and use anywhere ( their slogan ). Vue: learn multiple ways to use Vue and use some of those methods in different contexts for different situations.

2. Vue is simpler than React

I could not disagree more with this after using Vue. Vue's API surface is much larger in comparison to React, but this is not necessarily apparent. React takes a purist approach that only focuses on doing one thing, and doing it really well. React's primary objective is to keep your UI in sync with your data. It accomplishes this with minimal headaches, by using a declarative API, and component based structure. You do not need to worry or care about anything else in React aside from, providing data. Vue takes care of UI sync and then some.

Out of the box Vue offers a lot of really useful tools in addition to the more bare bones approach of React. Vue supports different templating approaches, animations, component slots, and is more loosely based on the upcoming W3C web components spec.

There are some very subtle differences in the Vue API approach vs the approach taken in React. The main export object Vue, is actually a stateful object, whose state ultimately affects the rendering functionality. Where as the approach taken in React, the main export React serves as more of a namespace for all of React's utilities. React's internal state is handled inside a black box we cannot touch, which is a good thing.

Typical Vue:

// Some HTML
<hello-wordpress id="app" />

// Some JS
Vue.component( 'hello-wordpress', {
  template: '<p>Hello WordPress!</p>'
} )

new Vue( {
  el: '#app'
} )

Typical React:

// This would usually be JSX, but not gonna use it.
const helloWordPress = () => React.createElement( 'p', {}, 'Hello WordPress!' )

ReactDOM.render( document.getElementById( 'app' ), helloWordPress )

Vue, once again, is slightly more concise. With the additional conciseness comes additional hidden complexity. Any reference to the root Vue instance could be used to override or goof up whatever Vue is doing. There is even an API used to interact with the main Vue instance after instantiation. In a project like WordPress where people often do whatever they want and write very yolo code ( me ). This unbounded extensibility could be a bad thing. React has only one way to extend itself; through creating and composing more components, which is simply how you use React.

In Vue you can create custom directives, components, mixins, many other customizations, all of these changes will need to happen before Vue instantiates, causing a time dependency. React, at the beginning, did similar things but the React team moved away from mixins etc. and instead started to reduce their API surface, taking a minimalist library approach.

3. React is potentially more flexible and powerful than Vue.

This is something I assumed would be the case. Flexible and powerful have ill-defined meanings in coding, but after taking Vue for a spin, I would have to argue that it is more powerful and flexible than React. However, the ways in which Vue is more flexible, are not necessarily always a good thing, and the ways in which React is more flexible, in the long run are most likely a good thing.

As said before, there is one way to do things in React, and many in Vue. On the surface this seems to be an aspect in favor of Vue. However, what happens if we need to switch off of Vue for some unforeseen reason in the future? Well it will certainly be much more difficult than the switch off of React is going to be. The fragmentation in the way Vue can be used will make an eventual departure away from it very difficult, and even while it is adopted there will probably be multitudes of conflict prone situations in an ecosystem like WordPress. There will certainly be much more technical debt accumulated by using Vue compared to React or Preact, but maybe that is not totally a bad thing.

If a strong commitment was made to Vue, maybe its additional feature set would be ultimately more useful than whatever technical conflicts could potentially arise out of the use of Vue. I got Vue up and running no problem, and someone who is new to the JS world could really do a lot with x-templates in a short amount of time. Vue and React, in my experience, from a purely productivity centric perspective, are major steps up from using jQuery and Backbone, when creating non trivial interfaces. Some of the additional syntax Vue uses in its template language make it really, really quick to get something up and running.

Is Vue the right fit for Gutenberg?

Not that my opinion matters or has much weight to it; I would have to say no. That is not a hard no by any means, and if Vue is chosen I will be happy. Vue is awesome and has many benefits, but for what Gutenberg is trying to achieve, I am not sure Vue is the ideal choice. I really have no idea what the ideal choice is to be honest, so, to wrap up, I will outline what is truly good about Vue, and what is not.

Why Vue could be the best fit

  1. It seems to have a lot of support from people in the WordPress community.
  2. It honestly does have a shorter learning curve for getting started. This is not something to be discarded, as I originally had thought.
  3. Productivity in Vue is great, but I haven't used it enough to know what walls are lurking in more complex uses of it.
  4. The Vue community is not currently larger than React's, but it most likely is larger than Preact's, and most of the other contenders'.

Why Vue might not be the best fit

  1. The vast ways in which Vue can be used, could further fragment WordPress.
  2. Although the initial learning curve is tame, the more advanced uses of Vue appear more complex than using React. There is also a considerable amount more to learn in Vue than React.
  3. Due to the nature of Vue's architecture, integrating with other libraries like TinyMCE ( a fundamental aspect of Gutenberg ), might be more difficult.
  4. Extensibility will probably be more challenging to implement in Vue as it further abstracts away from the core JavaScript language.
  5. Vue's divergence from the pure library approach, makes it a significant amount of extra technical debt to bring into Gutenberg.

That's five to four, Preact clearly wins. Just kidding. I do think Preact would be the most sensible choice though; speaking from a technical perspective. It is important to understand that the library chosen will not impact plugin/theme developers nearly as much as those who are contributing to Gutenberg/WordPress Core.

There are many efforts underway to allow custom blocks for Gutenberg to be written in just about any kind of JS you like. The choice of the library will have implications for WordPress developers though, because it will definitely make sense to use the same library, but it is important to understand that you are not being forced to use whatever library is chosen.

tl;dr

Yeah, this was a long post. Vue is really cool, I am enjoying it a lot, but ultimately I do not believe it is the right fit for Gutenberg, because despite what people assume, it carries more technical debt than a library similar to React does. The funniest part of all this debate is that realistically all of the options are quite good and phenomenal in their own way, so it is really hard to be certain that one option is better than the other.

I hope you stay tuned for more Gutenberg related content. I have some really awesome stuff that I will have ready soonish. I think Gutenberg will open up lots of opportunities beyond what WordPress, or anything for that matter, has really done before. Follow my blog if you want to keep up with Gutenberg related content, and see where the future might lead! I hope the original negativity that clouded this project will begin to fade and people will rally behind this project and support the Gutenberg team, who have been doing truly phenomenal work!

1 thought on “Gutenberg: A Change of Vue?

  1. We are using Vue for a large Laravel based projects and love it. As many do in the Laravel and WordPress community. Like PHP Vue is easy to get into and has multiple approaches to get things done. Also one of the reasons I initially fell in love with WordPress. It is very approachable. Even for people who are not JavaScript ninjas and or Vue novices. I see your concerns on technical debt and that may be so, but I’d say it is worth it. And with Laravel and WordPress supporting Vue things are even going to get better.

Leave a Reply

%d bloggers like this: