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
Heroicons v2 no longer allows importing icons from the package root `@heroicons/react`. The root entry (both ESM and CJS builds) is a Proxy whose `get` trap throws for every property access except `__esModule`. Icons must be imported from one of the versioned/style subpaths: `@heroicons/react/16/solid`, `@heroicons/react/20/solid`, `@heroicons/react/24/solid`, or `@heroicons/react/24/outline`.
Source
Thrown at react/index.esm.js:11
// The only reason this file exists is to appease Vite's optimizeDeps feature which requires a root-level import.
export default 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 imports to a versioned subpath, e.g. `import { BeakerIcon } from '@heroicons/react/24/outline'` (choose 16/20/24 size and solid/outline style).
- Run a codemod or global find/replace: change `from '@heroicons/react'` to the appropriate subpath based on the icon size/style you want.
- Check bundler/TS path aliases (tsconfig paths, webpack/vite aliases, jest moduleNameMapper) so `@heroicons/react/...` subpaths are not collapsed to the root entry.
- Clear the bundler cache and reinstall node_modules if stale v1-style resolution persists.
Example fix
// before
import { BeakerIcon } from '@heroicons/react'
// after
import { BeakerIcon } from '@heroicons/react/24/outline' Defensive patterns
Strategy: validation
Validate before calling
// fail fast at build/boot time instead of at render
import * as heroicons from '@heroicons/react'
if (heroicons && typeof heroicons === 'object' && !('BeakerIcon' in heroicons)) {
throw new Error("Do not import from '@heroicons/react'; use '@heroicons/react/24/outline' etc.")
} Prevention
- Use ESLint import/no-restricted-paths or no-restricted-imports to ban '@heroicons/react' root imports.
- Configure editor auto-imports / snippets to suggest '@heroicons/react/<size>/<style>'.
- Verify tsconfig/bundler aliases never collapse heroicons subpaths to the root.
- When upgrading majors, run a codemod over all icon imports before merging.
When it happens
Trigger: Any statement like `import { BeakerIcon } from '@heroicons/react'` or `require('@heroicons/react')` followed by property access on the module. The throw happens the moment the bundler/runtime resolves a named export from the root entry, because the Proxy get trap throws for every property except `__esModule`.
Common situations: Upgrading from Heroicons v1 (where root imports like `@heroicons/react/solid` patterns or auto-import suggestions resolved from the root) to v2; IDE/editor auto-import snippets that still target the bare package name; copy-pasted tutorials written for v1; bundler alias or path-mapping configuration that rewrites subpath imports back to the package root.
Related errors
- Importing from `@heroicons/react` directly is not supported.
- 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
- Importing from `@heroicons/vue` directly is not supported. P
AI-assisted analysis of tailwindlabs/heroicons@616b7a4dbb (2026-08-31).
Data as JSON: /api/errors/641799a6d644a365.
Report an issue: GitHub.