tailwindlabs/heroicons · error · Error
Importing from `@heroicons/react` directly is not supported.
Error message
Importing from `@heroicons/react` directly is not supported. Please import from either `@heroicons/react/16/solid`, `@heroicons/react/20/solid`, `@heroicons/react/24/solid`, or `@heroicons/react/24/outline` instead.
What it means
Identical to the ESM variant: the CommonJS entry `@heroicons/react/index.js` is a Proxy that throws on any property access. Heroicons v2 requires importing icons from the size/style subpaths (`16/solid`, `20/solid`, `24/solid`, `24/outline`) instead of the package root.
Source
Thrown at react/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/react\` directly is not supported. Please import from either \`@heroicons/react/16/solid\`, \`@heroicons/react/20/solid\`, \`@heroicons/react/24/solid\`, or \`@heroicons/react/24/outline\` instead.`
)
},
}
)
View on GitHub (pinned to 616b7a4dbb)
Solutions
- Rewrite requires/imports to a subpath: `const { BeakerIcon } = require('@heroicons/react/24/solid')` or `import { BeakerIcon } from '@heroicons/react/24/solid'`.
- If a tool resolved the CJS entry unexpectedly, prefer the ESM build or update the resolver config (jest moduleNameMapper, bundler mainFields) so subpath exports are honored.
- Audit auto-import settings/snippets so completions point at `@heroicons/react/<size>/<style>`.
- Ensure package.json `exports` of heroicons v2 is respected (Node >= 12.16 / bundler with exports support).
Example fix
// before
const { BeakerIcon } = require('@heroicons/react')
// after
const { BeakerIcon } = require('@heroicons/react/24/solid') Defensive patterns
Strategy: validation
Validate before calling
// guard CJS entry usage
const mod = require('@heroicons/react')
if (!mod || typeof mod !== 'object' || Object.keys(mod).length === 0) {
throw new Error("Root require of '@heroicons/react' is unsupported; require '@heroicons/react/24/solid' etc.")
} Prevention
- Ban root requires via lint rules (no-restricted-imports / node patterns).
- Keep Jest/Vitest moduleNameMapper entries mapping heroicons subpaths to their real builds.
- Prefer ESM builds where possible so subpath exports are honored.
- Grep CI for require('@heroicons/react') to catch regressions.
When it happens
Trigger: `require('@heroicons/react')` followed by destructuring or property access (e.g. `const { BeakerIcon } = require('@heroicons/react')`), or an ESM named import that Node resolves to the CJS root entry via interop. The Proxy get trap throws for every property except `__esModule`.
Common situations: Node CJS projects or test runners (Jest/Vitest with CJS transform) resolving the package to its main CJS entry; SSR/server code importing icons by the bare package name; editor auto-imports targeting the root; v1-era code after upgrading to v2.
Related errors
- Importing from `@heroicons/react` directly is not supported.
- Importing from `@heroicons/vue` directly is not supported. P
- You're trying to import `@heroicons/react/outline/${property
- You're trying to import `@heroicons/react/solid/${property}`
- Importing from `@heroicons/vue` directly is not supported. P
AI-assisted analysis of tailwindlabs/heroicons@616b7a4dbb (2026-08-31).
Data as JSON: /api/errors/3b0218505147566d.
Report an issue: GitHub.