Skip to content

@nuxt/icon server handler fails with compatibilityVersion >= 5 (ENOENT: .nuxt/imports) #467

Description

@sergeyd108

@nuxt/icon server handler fails with compatibilityVersion >= 5 (ENOENT: .nuxt/imports)

Environment

  • Nuxt: 4.3.1
  • @nuxt/icon: 2.2.1
  • Nitro: 2.13.1
  • Node: 22+
  • OS: Windows (also reproducible on other OSes)

Describe the bug

When using future: { compatibilityVersion: 5 } (or >= 5), running nuxt dev fails with:

[nitro] ERROR Error: Could not load .../.nuxt/imports
  (imported by .../node_modules/@nuxt/icon/dist/runtime/server/api.js): ENOENT: no such file or directory

The failing import is in @nuxt/icon/dist/runtime/server/api.js:

import { useAppConfig, getRequestURL, defineCachedEventHandler } from "#imports";

Root cause analysis

In Nuxt 4, server-side auto-imports in Nitro are disabled by default when compatibilityVersion >= 5.

This is controlled by experimental.nitroAutoImports, which resolves to:

  • true when future.compatibilityVersion < 5
  • false when future.compatibilityVersion >= 5

In @nuxt/nitro-server, that value decides whether Nitro gets imports: false or a real imports config:

imports: nuxt.options.experimental.nitroAutoImports === false ? false : { ... }

Then Nuxt merges user nitro config with defaults using defu(...). If the effective Nitro config ends up with:

  • imports: false → Nitro disables the unimport plugin entirely (no transform of #imports)

Because Nitro’s unimport transform is disabled, the from "#imports" in @nuxt/icon’s server handler is not transformed into concrete imports. Rollup then tries to resolve #imports via the Nuxt alias #imports -> .nuxt/imports, but in dev that file is not present on disk (only in Nuxt’s VFS), leading to ENOENT.

This means @nuxt/icon’s server handler currently depends on Nitro auto-imports being enabled, which is not true under compatibilityVersion >= 5.

Related context:

Minimal reproduction

Repo: https://github.com/sergeyd108/nuxt-icon-compat5-repro
Stackblitz: https://stackblitz.com/github/sergeyd108/nuxt-icon-compat5-repro

nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['@nuxt/icon'],
  future: { compatibilityVersion: 5 },
  compatibilityDate: '2026-02-28',
})

Commands:

pnpm install
pnpm dev

Workaround

Add an empty nitro.imports object to override imports: false during config merge:

export default defineNuxtConfig({
  // ...
  nitro: {
    imports: {},
  },
})

This makes Nitro treat imports as enabled again, so unimport transforms #imports usage in node_modules/@nuxt/icon/....

Suggested fix (in @nuxt/icon)

Avoid relying on #imports inside server runtime code. Replace #imports usage in runtime/server/api.js with explicit imports, for example:

- import { useAppConfig, getRequestURL, defineCachedEventHandler } from "#imports";
+ import { defineCachedEventHandler, getRequestURL } from "h3";
+ import { useAppConfig } from "nitropack/runtime";

This would make @nuxt/icon compatible with Nuxt 4 compatibilityVersion >= 5 where Nitro auto-imports are disabled by default.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions