---
title: "Nuxt 3.8"
description: "Nuxt 3.8 is out, bringing built-in DevTools, automatic Nuxt Image install, a new app manifest and much more."
canonical_url: https://nuxt.com/blog/v3-8
last_updated: 2026-04-15
---

# Nuxt 3.8

> Nuxt 3.8 is out, bringing built-in DevTools, automatic Nuxt Image install, a new app manifest and much more.

### 💻 CLI Improvements

Just to remind you, we're now using [the new Nuxt CLI](https://github.com/nuxt/cli) which is now versioned separately.

<tip>

You can now install a module with `nuxi module add <module-name>`

</tip>

<note icon="i-lucide-rocket">

We now share the same port with the Vite websocket, meaning better support for docker containers in development.

</note>

<read-more to="https://github.com/nuxt/cli/releases/tag/v3.9.0" icon="i-simple-icons-github" color="gray" target="_blank">

Read the Nuxt CLI `v3.9.0` release notes.

</read-more>

### ✨ Built-in Nuxt DevTools

Nuxt DevTools v1.0.0 is out and we now think it's ready to be shipped as a direct dependency of Nuxt.

<read-more to="/blog/nuxt-devtools-v1-0" icon="i-simple-icons-github" color="gray">

Check out Nuxt DevTools v1.0 announcement.

</read-more>

### 📸 Nuxt Image Auto-install

[`<NuxtImg>`](/docs/api/components/nuxt-img) and [`<NuxtPicture>`](/docs/api/components/nuxt-picture) first-class built-in components.

We now auto-installing `@nuxt/image` the first time that they are used ([#23717](https://github.com/nuxt/nuxt/pull/23717)).

<video :controls="true" className="rounded,dark:border,dark:border-gray-700" poster="https://res.cloudinary.com/nuxt/video/upload/v1697721767/nuxt3/nuxt-image-auto-install_uqkptq.jpg">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1697721767/nuxt3/nuxt-image-auto-install_uqkptq.webm" type="video/webm" />

<source src="https://res.cloudinary.com/nuxt/video/upload/v1697721767/nuxt3/nuxt-image-auto-install_uqkptq.mp4" type="video/mp4" />

<source src="https://res.cloudinary.com/nuxt/video/upload/v1697721767/nuxt3/nuxt-image-auto-install_uqkptq.ogg" type="video/ogg" />
</video>

<tip>

We advise using [`@nuxt/image`](https://image.nuxt.com) if you're using images in your site; it can apply optimisations to make your site more performant.

</tip>

### 📂 Deeper Layout Scanning

<caution>

This is a behaviour change so do take care with this one.

</caution>

We now support scanning layouts within subfolders in [`~/layouts`](/docs/guide/directory-structure/layouts) in the same way as we do with [`~/components`](/docs/guide/directory-structure/components).

<table>
<thead>
  <tr>
    <th>
      File
    </th>
    
    <th>
      Layout name
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      ~/layouts/desktop/default.vue
    </td>
    
    <td>
      'desktop-default'
    </td>
  </tr>
  
  <tr>
    <td>
      ~/layouts/desktop-base/base.vue
    </td>
    
    <td>
      'desktop-base'
    </td>
  </tr>
  
  <tr>
    <td>
      ~/layouts/desktop/index.vue
    </td>
    
    <td>
      'desktop'
    </td>
  </tr>
</tbody>
</table>

<read-more to="/docs/guide/directory-structure/layouts#named-layout">

Read more about **Named Layouts**.

</read-more>

### 📊 App Manifest

We now support a built-in app manifest (see [PR #21641](https://github.com/nuxt/nuxt/pull/21641)), which generates a manifest at `/_nuxt/builds/meta/<buildId>.json`.

It enables loading payloads **only for prerendered routes**, if a site is generated with `nuxt generate`, preventing 404s in the console.

It also enables **client-side route rules**. Only `redirect` route rules is supported for now; they will now redirect when performing client-side navigation.

<code-group>

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    '/about': { redirect: '/about-us' }
  }
})
```

```vue [pages/index.vue]
<template>
  <div>
    <!-- Will be redirected to /about-us on client-side -->
    <NuxtLink to="/about">About</NuxtLink>
  </div>
</template>
```

</code-group>

<tip icon="i-lucide-rocket">

The app manifest also enables future enhancements including detection of a new deployment by checking `/_nuxt/builds/latest.json`.

</tip>

<note>

You can **opt-on from this behaviour if you need to** by setting `experimental.appManifest` to `false` in your `nuxt.config.ts` file.

</note>

### 🤝 Scope and Context Improvements

We now define a 'scope' for Nuxt composables executed in plugins ([#23667](https://github.com/nuxt/nuxt/pull/23667)), which allows running synchronous cleanup before navigating away from your site, using the Vue [`onScopeDispose`](https://vuejs.org/api/reactivity-advanced.html#onscopedispose) lifecycle method.

<note>

This should fix an edge case with cookies ([#23697](https://github.com/nuxt/nuxt/pull/23697)) and also improves memory management such as Pinia stores ([#23650](https://github.com/nuxt/nuxt/issues/23650)).

</note>

<read-more to="https://vuejs.org/api/reactivity-advanced.html#effectscope" icon="i-simple-icons-vuedotjs" target="_blank">

Read more about Vue effect scopes.

</read-more>

We also now support [**native async context**](https://nodejs.org/api/async_context.html) for the *Vue composition API* ([#23526](https://github.com/nuxt/nuxt/pull/23526)). In case you're unaware, we support native async context on Node and Bun, enabled with [`experimental.asyncContext`](/docs/guide/going-further/experimental-features#asynccontext).

If you experience issues with `Nuxt instance unavailable`, enabling this option may solve your issues:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  experimental: {
    asyncContext: true
  }
})
```

<note>

Once we have cross-runtime support, we will enable it by default.

</note>

### 🔗 NuxtLink Defaults

You can define your own [`<NuxtLink>`](/docs/api/components/nuxt-link) components with the [`defineNuxtLink`](/docs/api/components/nuxt-link#definenuxtlink-signature) utility.

Today, you can cutomize the options for the built-in [`<NuxtLink>`](/docs/api/components/nuxt-link), directly in your `nuxt.config.ts` file ([#23724](https://github.com/nuxt/nuxt/pull/23724)).

This can enable you to enforce trailing slash behaviour across your entire site, for example:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  experimental: {
    defaults: {
      nuxtLink: {
        activeClass: 'nuxt-link-active',
        trailingSlash: 'append'
      }
    }
  }
})
```

### ⚡️ Data Fetching Improvements

We have two very significant new features for [`useAsyncData`](/docs/api/composables/use-async-data) and [`useFetch`](/docs/api/composables/use-fetch):

1. You can now set `deep: false` to prevent deep reactivity on the `data` object returned from these composables ([#23600](https://github.com/nuxt/nuxt/pull/23600)). It should be a performance improvement if you are returning large arrays or objects. The object will still update when refetched; it just won't trigger reactive effects if you change a property deep within the `data`.
2. You can now use the `getCachedData` option to handle custom caching for these composables ([#20747](https://github.com/nuxt/nuxt/pull/20747))

```vue [pages/index.vue]
<script setup>
const nuxtApp = useNuxtApp()
const { data } = await useAsyncData(() => { /* fetcher */ }, {
  // this will not refetch if the key exists in the payload
  getCachedData: key => nuxtApp.payload.static[key] ?? nuxtApp.payload.data[key]
})
</script>
```

<video-accordion title="Watch the video from Alexander Lichter about Client-side caching with getCachedData." video-id="aQPR0xn-MMk">



</video-accordion>

We also support configuring some default values for these composables in an app-wide way ([#23725](https://github.com/nuxt/nuxt/pull/20747)):

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  experimental: {
    defaults: {
      useAsyncData: {
        deep: false
      },
      useFetch: {
        retry: false,
        retryDelay: 100,
        retryStatusCodes: [500],
        timeout: 100
      }
    }
  }
})
```

### 🔢 Layer Improvements

We now more carefully load layer plugins ([#22889](https://github.com/nuxt/nuxt/pull/22889) and [#23148](https://github.com/nuxt/nuxt/pull/23148)) and middleware ([#22925](https://github.com/nuxt/nuxt/pull/22925) and [#23552](https://github.com/nuxt/nuxt/pull/23552)) in the order of the layers, always loading your own plugins and middleware last. This should mean you can rely on utilities that layers may inject.

And probably one of the most significant changes - if you are using remote layers we now clone these within your [`node_modules/`](/docs/guide/directory-structure/node_modules) folder ([#109](https://github.com/unjs/c12/pull/109)) so layers can use dependencies with your project. See [`c12` release notes](https://github.com/unjs/c12/releases/tag/v1.5.1) for full details.

<tip icon="i-lucide-check-circle">

We've also added a test suite to cover these layer resolution changes.

</tip>

### 😴 Nightly Release Channel

Every commit to the `main` branch of Nuxt is automatically deployed to a new release, for easier testing before releases. We've renamed this from the 'edge release channel' to the 'nightly release channel' to avoid confusion with *edge deployments*. And probably also with Microsoft Edge (though I haven't heard that anyone was confused with that one!)

- `nuxt3` is now `nuxt-nightly`
- `nuxi-edge` is now `nuxi-nightly`
- `@​nuxt/kit-edge` is now `@​nuxt/kit-nightly`
- ... and so on.

<read-more to="/docs/guide/going-further/nightly-release-channel#nightly-release-channel">

Read more about the **Nighly Release Channel**.

</read-more>

### ⚗️ Nitro v2.7

Nitro v2.7 has been released with lots of improvements and bug fixes.

<tip icon="i-lucide-rocket">

🔥 One of the most significant is that we now save **40% of bundle size in production** by using native `fetch` supported in Node 18+ ([#1724](https://github.com/unjs/nitro/pull/1724)). So if possible, we'd recommend you update your Node version to at least 18.

</tip>

<read-more to="https://github.com/unjs/nitro/releases/tag/v2.7.0" icon="i-simple-icons-github" color="gray" target="_blank">

Check out Nitro v2.7 release note.

</read-more>

### 💪 Type Import Changes

<warning>

This is likely to need code changes in your project.

</warning>

Vue requires that type imports be explicit (so that the Vue compiler can correctly optimise and resolve type imports for props and so on). See [core Vue `tsconfig.json`](https://github.com/vuejs/tsconfig/blob/main/tsconfig.json#L30-L33).

We've therefore taken the decision to turn on `verbatimModuleSyntax` by default in Nuxt projects, which will throw a type error if types are imported without an explicit `type` import. To resolve it you will need to update your imports:

```diff
- import { someFunction, SomeOptions } from 'some-library'
+ import { someFunction } from 'some-library'
+ import type { SomeOptions } from 'some-library'
```

You may also encounter modules in the Nuxt ecosystem that need to be updated; please open an issue for those modules. I'm also very happy to help if you're encountering any problems with this, if you're a module author. Just tag me and I'll take a look.

If for whatever reason you need to undo this change in your project you can set the following configuration:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  typescript: {
    tsConfig: {
      compilerOptions: {
        verbatimModuleSyntax: false
      }
    }
  }
})
```

However, we'd recommend only doing that temporarily, as Vue does need this option to be set for best results.

## ✅ Upgrading

As usual, our recommendation for upgrading is to run:

```sh
npx nuxi upgrade
```

## Full Release Notes

<read-more to="https://github.com/nuxt/nuxt/releases/tag/v3.8.0" icon="i-simple-icons-github" color="gray">

Read the full release notes of Nuxt `v3.8.0`.

</read-more>

Thank you for reading this far! We hope you enjoy the new release. Please do let us know if you have any feedback or issues.

**Happy Nuxting ✨**
