Recently, a Tweet recommending people to learn Vue before React caught my eye. Hey, that’s what I did! I got started with web development via Vue and later learned React to, in part, further improve my chances in switching careers. (My job title then was Research Analyst.) That was more than four years ago alreday—how time flies!
Then I remembered my earlier blog post on my first look into React from the perspective of someone who used and appreciated Vue. There, I briefly touched on three points: barriers to entry, code structure, and experience of using the official starter. Well, I now have been paid to build React apps for years and, meanwhile, the overall landscape has changed considerably. Maybe this is a good time to revisit the comparisons I made then—I’m curious to see how my opinion has changed.
A quick disclaimer: While I’ve been (casually) following Vue’s development, I haven’t really built or maintained any Vue app recently.
Barriers to entry
I wrote that React seemed to have higher barriers to entry than Vue. Today, I’m not so sure. Since the introduction of the Composition API, the flagship feature of Vue 3, Vue has opened up the full power of its reactivity model to the users via an interface that draws inspiration from React’s Hooks. Saving the flexibility it offers in code structure the next point, I believe that Vue 3 dramatically increased Vue’s API surface and raised the barriers to entry. While they share the templating part of authoring Vue components, these two API styles are radically different, and users are left to wonder which one to pick. From the official docs:
Which to Choose?
Both API styles are fully capable of covering common use cases. They are different interfaces powered by the exact same underlying system. In fact, the Options API is implemented on top of the Composition API! The fundamental concepts and knowledge about Vue are shared across the two styles.
In fact, much of Vue’s official docs is split into two parts, one based on the Options API and the other on the Composition API, with a toggle to switch between the two. This is very different from how React introduced its Hooks API, i.e. as the new definitive way to write React components. Vue chose not to play favorites, burdening its users with the choice.
Does this make Vue more difficult to get into than React today? Probably not—Vue is still a largely approachable framework. Plus, I’m not aware of any evidence that introducing the Composition API has hurt Vue’s adoption. Meanwhile, React is currently going through a fundamental transformation with the new React Architecture and RSC, demaning its users to relearn how React works. Furthermore, React is now publicly experimenting and itereating on this transformation through Next App Router, which has caused much frustration on a certain portion of the community who feel as though the ground is moving under their feet. In sum, learning Vue is not much harder and learning (new) React is not made any easier than before.
I wrote that React components seemed less structured than Vue’s. This is still true although to a lesser extent with the Composition API. Vue SFC still imposes a clear separation between structure, style, and logic even though the Composition API allows a greater degree of flexibility in the logic portion. And, of course, the structure of React components is just as flexible as before.
I also felt strongly that the flexibility in component structure would be inversely proportional to code maintainabiltiy. I no longer subscribe to this view. Instead, I’m now convinced that the rigid structure imposed by both the Options API and SFC can be rather detrimental to maintainability. In fact, Vue team presented greater flexibility in code organization as one key benefit of the Composition API over the Options API. I agree.1
As for SFC, it adds (largely unnecessary, I now believe) friction to turning a piece of code into a new component. All things being equal, this friction makes it more costly to refactor or experiment with respect to component boundary, and, in turn, incentivizes developers to let components grow too large in size and scope. While Vue’s reactivity means it doesn’t suffer from excessively re-running the whole component body like React does, a huge component code is in itself code smell and an enemy of maintainability.
Does this mean Vue apps are somehow bound to be less maintainable than React apps? Not at all! While it adds extra friction, Vue SFC format does not stop anyone from breaking a large component into smaller ones just as React Hooks does not stop anyone from creating a gaint mess of a component. Plus, even though SFC is the recommended approach for using Vue, it is still possible to opt out.
I wrote that Create React App was less flexible than Vue CLI. Well, funnily enough, both projects are now basically dead! The Create React App repo has seen little active development for years now, and Vue CLI entered the “maintenance mode” in the beginning of 2022.
Instead, React now officially recommends starting new projects with frameworks like Next and Remix. As for Vue, the official “Quick Start” page recommends
create-vue, a CLI tool to quickly scaffold Vite-powered Vue projects. Nuxt gets a couple of mentions in the docs, but it’s not at the forefront.
Here, I do prefer the Vue way—which I believe is more commen in other frameworks as well. Start with the core UI framework, and later proceed to the more holistic web framework as needed.
To me, React’s recommendation to start with a React framework feels a bit heavy-handed as it comes with the burden of choosing a framework as well as learning it. Sure, most “production-grade” apps will benefit from what each React framework offers out of the box, and not using one may lead to “creating your own framework—albeit one with no community or upgrade path (and if it’s anything like the ones we’ve made in the past, more haphazardly designed).” Even still, starting one’s React journey with a framework feels upside down. In my view, this recommendation makes more sense for seasoned developers as well as professionals.
Again, instead of conclusion
Incidently, today I watched a short video essay on choosing JS framework and tech stack. The main point was, to paraphrase a bit, how technology is ultimately a tool and what matters the most is what we build with it. I wholeheartedly agree!
This, of course, doesn’t mean we should stop exploring new tools, new idea, new approaches and comparing them to what we already know. In fact, it can be not only fun but also instructive to consider multiple solutions to a problem. Each solution embodies an experiment, a vision, a set of trade-offs as well as a value system to weigh different trade-offs differently. And through constrast between solutions, we gain a deeper insight into each. This is a win-win game: either we find a better solution for our problem or gain a renewed appreciation as well as a greater understanding of what we have!
One important caveat here is that this requires some discipline of the developers. And we all know how unreliable humans can be. No free lunch, no silver bullet. But I think the trade-off ultimately favors flexibility over rigidity. ↩