Skip to content

Instantly share code, notes, and snippets.

@james2doyle
Last active January 16, 2024 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save james2doyle/63a04ca610c98981a27e95ca93983992 to your computer and use it in GitHub Desktop.
Save james2doyle/63a04ca610c98981a27e95ca93983992 to your computer and use it in GitHub Desktop.
A comparison between using Nuxt/Vue and Next/React

It is easier to make things great in Vue

TLDR: It is easier to make things great in Vue because it helps you and requires less magic and complexity.

I’ve been playing with the latest version of Nuxt over the last few weekends.

I’ve been using a recent Next (v13) site as the base for a project. I have the basic top level routes recreated now.

So I have touched all the major parts. These are my thoughts on the reasons I think Vue is better than React for content driven sites.

Here are some of the takeaways:

For Vue

  • Incredible stability with Vue 3 (released Sep 18, 2020, still the working version) and no plans to break things
  • Reactivity system makes DOM updates rather than full renders. So toggling classes is exactly that, instead of re-rendering the entire component. This is called a patch flag
  • You can be sure that code you expect to run once only runs once without special attention
  • Provide & Inject work in SSR with less caveats than Context & Providers in React because those are considered "client only"
  • Automatic fallthrough of attributes (and no cleanProps required)
  • Less hydration mismatch errors because of v-show (keep all the DOM you need, just hide it)
  • The KeepAlive component allows you to keep state localized instead of moving it up the tree
  • Using a named slot is much easier than using children in props or making render props
  • Easier conditions with v-if, v-else, and v-show
  • Control flashing/shifting content with v-cloak
  • List rendering is much nicer with v-for (plus it can go directly on a Component instead of needing a wrapper)
  • No useCallback or useMemo jargon, instead there is v-once and v-memo (or even KeepAlive)
  • No need for Fragment because multiple root elements are allowed
  • No need for Suspense but it exists in case you want to handle loading in your template instead of your dynamic component loader
  • Built in Transition component for animations
  • You don't need to alias any of the HTML attributes (ex: class vs. className)

For Nuxt

Some downsides

  • Working with TypeScript can be odd. There are some weird quirks using it. Most are well documented and can be solved with nice plop files or linting
  • The way to generate the routes in Nuxt that need to be pre-rendered is a bit wonky. You need to make a module and it is not defined in the page level
  • Nuxt auto imports are cool but the editor integrations often need to be restarted in order to pick up the changes
  • Nuxt auto imports can also be tricky because Types need to be imported but not modules
  • Nuxt 3rd party components always need to be imported unless added to auto imports

Coming from React

Conventions in React don’t translate fully to Vue in that large blocks of JS before your template are usually not required. The templating in Vue is much more expressive so you don’t need that huge JS block.

You have no "returns" in Vue, so you end up moving that logic to the template. You can use "if-else" to choose which component to render, or using the built in Component tag, to select one dynamically. This can be really nice when you have a component that you want to set as a specific element based on it’s props. Think the Button component that can be an a tag (a, input[type=submit]) or a literal type=button.

Classes are much easier to handle in Vue, so you don’t need the big setup in the front that massages all the classes. You can do this, but it generally isn’t needed. Basically, clsx is built-in.

With better conditionals, your templates are immediately more understandable at a glance. It is clear in the first prop on your component if it will render or not.

The slot concept is just so much nicer than props.children and render props.

Using v-show can help reduce hydration errors since you are still rendering the elements in the output, when the client calls kick in, then the client code takes over. This can be done in React, but you would have to make it a client component as well as use a className to toggle the visibility like v-show would.

There was never really a reason to even thing about doing any memoization. It just didn't come up. Because of the way Vue renders, you don't have to optimize for a render loop in the same way you do in React.

It may look on the surface like Vue has a smaller ecosytem, but I think that is partially because Vue has things inclueded that you don't need a dependency for. There is no need for clsx or an animation tool, because class and transition are capable features that are already included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment