Will Nuxt 3 Make Vue.js Great Again? | by Jose Granja | May, 2022

Lighter, faster, auto-imports, awesome developer experience

Picture by Author

Recently we have had exciting releases for the React ecosystem. First, it was Next.jsthen came Remixand later on React 18. Those were stealing the thunder of any JavaScript framework. They were driving all the frontend discussions and increasing React’s momentum.

Luckily, the Nuxt team is making a big comeback with its latest Nuxt 3 version. It is currently in RC and the stable release is due in June. As great as a Vue.js is, it will fail to gain traction if it lags behind in framework features. This version might play a big role in increasing its popularity 🚀.

What is Nuxt anyway? You can think of it as the Remix/Next.js equivalent written in Vue.js. It is an isomorphic JavaScript framework that empowers us to write code that executes both on the client and on the server. It abstracts all the complexity and configuration away.

The new Nuxt 3 release is packed with many features. Not only to create performant web applications but also to raise the developer experience to a whole new level. It has built-in TypeScript support which is awesome. The only obvious caveat is that it is highly opinionated. It’s a tall we need to pay for. However, seeing how amazing this evolution is, I will happily pay for it.

In this article, I will summarise some of the greatest features that might hopefully lead many developers to switch from React.

This new version of Nuxt is powered by a new server engine which is nicknamed Nitro. It is built from the ground up, meaning no legacy code.

What are its features?

  • Cross-platform support for Node.js, Browsers, service-workers, and more: it makes the engine platform-agnostic
  • Serverless support
  • API routes: it is powered internally by the unjs/h3 project.
  • Automatic code-splitting
  • Hot module downloading
  • Hybrid mode: granularly controlling how your pages are rendered. More on that in the next section.

In summary, we get a great engine that is not only able to power SSR. We can create static, spaor event api applications. The fact that it is platform agnostic and lightweight makes it super powerful. It does not only mean faster response times but the liberty to host the application where we like to. We can now deploy our code directly on the edge. That means the SSR code is executed as close as possible to the end-user.

Currently the Nuxt framework supports two rendering modes:

  • Client-side: the browser downloads all the JavaScript files and then it generates the HTML elements
  • Server-side: The server generates the HTML page and returns it back to the client. The client is then hydrated to add the interaction.

Each of those approaches has its pros and cons. For example, server-side rendering is more expensive since we are computing the view in our hosting. However, client-side does not play well with SEO.

In prior versions, we had to choose either one or the other approach for the whole application. In this new release, we have a Hybrid Rendering. We can customize the behavior on a per route basis.

In summary, we have more granular control over which routes we want to be using SSR and which not. It lets us enjoy the pros of each approach and design our web application accordingly.

⚠️ This might not be part of the first stable release but will be coming shortly after.

Imports are a trivial task. It is such boring work that we normally rely on tooling to handle those (VSCode extensions) and some to order those (ESLint). What if they were not needed?

That is exactly what is happening on Nuxt 3. We won’t need to add any import statements anymore. It will be worked out automatically by the engine. How will Nuxt know how to resolve those? They are based on a directory and naming structure.

  • components/ — this is where Vue components should be placed.
  • composables/ — this is where Vue compostables should be placed.


Let’s say we created a components/Foo.vue:


To use this component all we have to do is use it in our .vue template file matching the component file name.

<Foo />

How does that happen? Internally the engine creates everything in the .nuxt folder. We can inspect the .nuxt/components.d.ts and find our components definition there.

Dynamic Imports

What if we wanted to import that component in a Lazy way? It can be easily done by prefixing Lazy to the component Name.

<LazyFoo /> // component will be lazy loaded

Nested Components

What if the component is in a nested directory? We just have to amend the path directory to the component’s name. For example components/bar/foo.vue .

<BarFoo />

💁‍♂️ It is recommended to name the component components/bar/BarFoo.vue for consistency though.

Client Specific Components

What if we want to make that component Client only? We can use the ClientOnly wrapper.

<LazyFoo />

Explicit Imports

We can use explicit imports if needed by using the #components in this scenario.

import { Foo } from '#components';

The documentation is great. There is the traditional API that can be found here.

However, there is an interesting and intuitive guide to get started here. It is still a work in process but helps us understand the Nuxt project in an easy way. As Nuxt has a lot of features scoped by folder it can be hard to understand at first. Some directors participate in some file-based routing.

Here are some examples on the folders we might find:

  • pages: file-based routing to create routes within your web application through Vue Router.
  • server: folder scanned to register API and server handlers with HMR support.
  • public: where we need to put our assets
  • components: all the components that are exportable from any page.
  • plugins: directory where we need to place our imported plugins.

In order to quickly grasp this, you can find in this guide the complete tree of any Nuxt project.

Caption from https://v3.nuxtjs.org/guide/directory-structure/components

There are also some interactive examples that can be found here. Those have links to CodeSandBox or StackBlitz.

Currently, the JavaScript frameworks really take into consideration the developer experience. There is great support for TypeScript is Nuxt 3. We can combine the API typings with our components which wraps the whole thing together nicely.

Also, we can now use the latest fancy building tools for building our projects. It makes the whole experience more snappy.

Out of the box Nuxt 3 supports:

  • Vite
  • webpack 5+ esbuild
  • PostCSS

The default builder is Vite but switching to Webpack5 is easy but simplifying tweaking the nuxt.config.ts file:

export default defineNuxtConfig({
vite: false

You might extend any config by using

  • extendWebpackConfig(callback, options?)
  • extendViteConfig(callback, options?)
  • addWebpackPlugin(webpackPlugin, options?)
  • addVitePlugin(vitePlugin, options?)

Thanks to the modern JavaScript compilers we can expect lighting faster build time and a better developer experience.

We have seen how great and important this release is. Hopefully, it will help increase the interest of Vue.js. It is awesome to have diversity since competition brings many good ideas. That is how innovation is driven forward.

We can see how React is dominating JavaScript’s View ecosystem.

Picture from www.npmtrends.com.

React’s community is bigger and it is easier to land a job. However, tools like Nuxt 3 might be able to balance the scales.

Interesting, it is a great time for being a web developer. We have plenty of great choices. Do we go for Remix, Next.jsor Nuxt.js? We can’t possibly go wrong with any of those. It will all boil down to our personal preferences.

Leave a Comment