@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:
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.
@nuxt/iconserver handler fails withcompatibilityVersion >= 5(ENOENT: .nuxt/imports)Environment
@nuxt/icon: 2.2.1Describe the bug
When using
future: { compatibilityVersion: 5 }(or>= 5), runningnuxt devfails with:The failing import is in
@nuxt/icon/dist/runtime/server/api.js: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:truewhenfuture.compatibilityVersion < 5falsewhenfuture.compatibilityVersion >= 5In
@nuxt/nitro-server, that value decides whether Nitro getsimports: falseor a real imports config:Then Nuxt merges user
nitroconfig with defaults usingdefu(...). 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#importsvia 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 undercompatibilityVersion >= 5.Related context:
Minimal reproduction
Repo:
https://github.com/sergeyd108/nuxt-icon-compat5-reproStackblitz:
https://stackblitz.com/github/sergeyd108/nuxt-icon-compat5-repronuxt.config.ts:Commands:
Workaround
Add an empty
nitro.importsobject to overrideimports: falseduring config merge:This makes Nitro treat imports as enabled again, so unimport transforms
#importsusage innode_modules/@nuxt/icon/....Suggested fix (in
@nuxt/icon)Avoid relying on
#importsinside server runtime code. Replace#importsusage inruntime/server/api.jswith explicit imports, for example:This would make
@nuxt/iconcompatible with Nuxt 4compatibilityVersion >= 5where Nitro auto-imports are disabled by default.