Elijah Asaolu I am a programmer, I have a life.

What’s new in Nuxt 3

4 min read 1125

What's New in Nuxt 3

The long-awaited Nuxt 3 beta was launched on 12 October 2021, making it a momentous day for the Nuxt and Vue developer ecosystems. This is an updated version that has been rearchitected for improved performance and lighter builds. And in this article, we will look at the new features in Nuxt 3, as well as the installation process and how to migrate your existing Nuxt apps (Nuxt 2) to this latest version.

Migrating from Nuxt 2 to Nuxt 3

N.B., before we begin, please keep in mind that Nuxt 3 currently only supports Node v14 or v16.

While there is currently no stable migration technique for a smooth transition from Nuxt 2 to Nuxt 3, Nuxt Bridge (which we will discuss in more detail later) can be used to try out some of the new capabilities of Nuxt 3 in prior versions.

To do this, first delete any package-lock files (package-lock.json or yarn.lock) from your project, then remove the Nuxt dependency and create a new entry in your package.json file for the most recent version of nuxt-edge:

- "nuxt": "^2.15.0"
+ "nuxt-edge": "latest"

The next step is to reinstall all of your dependencies:

npm install
# OR
yarn install

And you are ready to go!

You can also choose to install Nuxt Bridge as a development dependency:

npm install -D @nuxt/[email protected]:@nuxt/bridge-edge
# OR
yarn add --dev @nuxt/[email protected]:@nuxt/bridge-edge

However, doing so will also require updating your package.json file to reflect the fact that Nuxt will now generate a Nitro server as a build result.

Starting a new project

The process of creating a new application in Nuxt 3 differs significantly from earlier versions. Because Nuxt 3 is still in beta, you’ll have to start by initializing a fresh app:

npx nuxi init project-name

The next step is to install the dependencies that were included in the generated package.json file:

cd project-name
npm install
# OR 
yarn install

Once these steps are completed, we can go ahead and start our application:

npm run dev
# OR 
yarn dev

If everything works fine, a browser window should automatically open for http://localhost:3000 with an output like in the image below:

Nuxt 3 localhost

What’s new in v3

Nitro Engine

Nuxt 3 has a new cross-platform server engine that adds full-stack capabilities to Nuxt applications. Nitro engine also includes out-of-the-box serverless functionality and is believed to be the first JavaScript application server that works with a wide range of current cloud hosting services. This makes integrating APIs into your Nuxt apps a breeze.

To use this functionality, just create a new /server directory in your project root folder. This directory will hold your project’s API endpoints and server middleware, and Nuxt will automatically read any files in the /server/api directory to create API endpoints:

// server/api/hello.js
export default async (req, res) => {
  return {
    foo: "bar",

This will generate a new API endpoint that can be accessed at http://localhost:3000/api/hello.

Server middleware

Nitro Engine also supports adding middleware to API endpoints. Similar to how an API works, Nuxt will read any files in the /server/middleware directory to generate server middleware for your project. But unlike API routes, which are mapped to their own routes, these files will be executed on every request. This is usually done so that you may add a common header to all responses, log responses, or alter an incoming request object.

Below is an example that adds someValue to every API request:

// server/middleware/addValue.js
export default async (req, res) => {
  req.someValue = true

Nuxt Bridge

Nuxt 3 now includes Nuxt Bridge, a forward-compatibility layer that enables you to access many of the new Nuxt 3 features by simply installing and activating a Nuxt module.

You can use Nuxt Bridge to ensure that your project is (nearly) ready for Nuxt 3 and that your developers have the greatest experience possible without having to do a large rewrite or risk breaking modifications.

While we’ve already discussed how migration with Nuxt Bridge works, you can learn more about Nuxt Bridge here.


Nuxt Context, which provides access to runtime app context from within composables, components, and plugins, has now been renamed to NuxtApp in Nuxt 3.

And within components and plugins, we can access NuxtApp with useNuxtApp:

import { useNuxtApp } from "#app";

function useMyComposable() {
  const nuxtApp = useNuxtApp();
  // access runtime nuxt app instance

In addition, the inject function, which makes functions and/or values available across your Nuxt application, is now known as provide.

For example, creating a plugin that logs a provided name to the console in Nuxt 2:

// plugins/hello.js
export default ({ app }, inject) => {
  inject("hello", (name) => console.log(`Hello ${name}!`));

// Can be accessed using

In Nuxt 3, it becomes this:

const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => console.log(`Hello ${name}!`))

// Can be accessed using

New file structure

The pages/ directory is now optional in Nuxt 3, and if it is not there, Nuxt will not include the vue-router dependency. Instead, the new app.vue serves as the core component of your Nuxt application; everything you add to it (JS and CSS) will be global and included on all pages.

This is advantageous when working on a one-page application, such as a landing page, or an application that does not require routing.

Composables directory

Nuxt 3 also includes support for a new composables/ directory that is used for auto-importing Vue composables into your application.

If you are not already familiar with what composables are in Vue, this was introduced in Vue 3, and you can learn more about composables here.

With the Nuxt composable directory, we can easily create both named and default composables.


// composables/useFoo.js
import { useState } from '#app'

export const useFoo = () => {
  return useState('foo', () => 'bar')

Our composable is exported as useFoo in this case; if no export name is supplied, the composable will be accessible as the pascalCase of the file name without the extension.

They are also auto-imported, and we can access them in any page or component:

    {{ foo }}

<script setup>
const foo = useFoo()

Vue 3 and Vite support

Nuxt 3 was designed to work with Vue 3. Because Nuxt 3 is developed in Vue 3, you’ll have access to features like the Composition API, enhanced module imports, and better overall app speed. Vite support is included in Nuxt 3, and it is backward compatible with Nuxt 2.

More great articles from LogRocket:


In this post, we’ve gone through the new features in Nuxt 3, as well as how to convert existing Nuxt apps to this newest version.

You should keep in mind that Nuxt 3 is still in beta, so anticipate things to break. It is also recommended that you do not utilize it in production until the first stable release.

Get set up with LogRocket's modern error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin
Get started now
Elijah Asaolu I am a programmer, I have a life.

Leave a Reply