tailwindlabs/heroicons · error · Error
Importing from `@heroicons/vue` directly is not supported. P
Error message
Importing from `@heroicons/vue` directly is not supported. Please import from either `@heroicons/vue/16/solid`, `@heroicons/vue/20/solid`, `@heroicons/vue/24/solid`, or `@heroicons/vue/24/outline` instead.
What it means
CJS counterpart of the Vue root guard: `@heroicons/vue/index.js` is a Proxy that throws on any property access. Heroicons v2 for Vue requires size/style subpath imports; the root entry exists only to fail loudly with guidance.
Source
Thrown at vue/index.js:11
// The only reason this file exists is to appease Vite's optimizeDeps feature which requires a root-level import.
module.exports = new Proxy(
{},
{
get: (_, property) => {
if (property === '__esModule') {
return {}
}
throw new Error(
`Importing from \`@heroicons/vue\` directly is not supported. Please import from either \`@heroicons/vue/16/solid\`, \`@heroicons/vue/20/solid\`, \`@heroicons/vue/24/solid\`, or \`@heroicons/vue/24/outline\` instead.`
)
},
}
)
View on GitHub (pinned to 616b7a4dbb)
Solutions
- Use a subpath import: `import { BeakerIcon } from '@heroicons/vue/24/solid'` (or the matching require form).
- Update resolver/test config (moduleNameMapper, aliases) so subpath imports resolve to the subpath builds.
- Ensure the runtime honors package `exports` so the CJS root is only hit by genuine root imports.
- Grep the codebase for `from '@heroicons/vue'` / `require('@heroicons/vue')` and migrate each occurrence.
Example fix
// before
const { BeakerIcon } = require('@heroicons/vue')
// after
const { BeakerIcon } = require('@heroicons/vue/24/solid') Defensive patterns
Strategy: validation
Validate before calling
// CJS/SSR guard
const mod = require('@heroicons/vue')
if (!mod || typeof mod !== 'object' || Object.keys(mod).length === 0) {
throw new Error("Root require of '@heroicons/vue' is unsupported; require '@heroicons/vue/24/solid' etc.")
} Prevention
- Ban root requires in Nuxt/Node server code via lint rules.
- Ensure the runtime/bundler respects package.json exports.
- Grep CI for require('@heroicons/vue') to catch regressions.
- Update test-runner moduleNameMapper entries when upgrading heroicons.
When it happens
Trigger: `const { BeakerIcon } = require('@heroicons/vue')` or an ESM import that Node resolves through the CJS root entry, followed by property access. The Proxy get trap throws for everything except `__esModule`.
Common situations: Nuxt/Node SSR or test environments resolving the CJS main entry; CommonJS-based Vue toolchains; v1-era code after upgrading; bundler configurations ignoring package `exports`.
Related errors
- Importing from `@heroicons/react` directly is not supported.
- Importing from `@heroicons/vue` directly is not supported. P
- Importing from `@heroicons/react` directly is not supported.
- You're trying to import `@heroicons/vue/outline/${property}`
- You're trying to import `@heroicons/vue/solid/${property}` f
AI-assisted analysis of tailwindlabs/heroicons@616b7a4dbb (2026-08-31).
Data as JSON: /api/errors/e6d396a1ad66eb37.
Report an issue: GitHub.