← Back to archive

Repo of the Day

unplugin/unplugin-icons

Published: Sep 20, 2021

Open repository ↗

🤹 Access thousands of icons as components on-demand universally.

Summary

unplugin-icons is a build-time tool that exposes icons from many icon sets as components for popular frameworks. It works across Vite, Webpack, Rollup, Nuxt, Rspack, and more, drawing icon data from Iconify's library of about 150 sets and over 200,000 icons. The plugin only bundles the icons a project actually imports, so the runtime cost stays small.

What it is useful for

This is useful when a team wants to pull icons from multiple sources (Material Design Icons, Carbon, Tabler, etc.) without adding several icon libraries to a project. It supports React, Vue 3, Vue Vapor, Solid, Svelte, Qwik, and Ember, so a single approach covers most front-end stacks. On-demand bundling avoids shipping unused icons, and SSR/SSG setups benefit because icons ship inline with the page rather than as a separate runtime request. It also helps when an app has its own SVG assets: custom collections can be loaded from the file system, a remote URL, an inline string, or a third-party npm package that ships icons in Iconify's JSON format.

How engineers can use it

  1. Install the plugin: npm i -D unplugin-icons.
  2. Install icon data. The README offers three choices: the full collection (npm i -D @iconify/json, roughly 120MB), individual sets like npm i -D @iconify-json/mdi @iconify-json/carbon, or experimental autoInstall: true that detects your package manager and installs on demand.
  3. Add the plugin to the build tool config, for example in vite.config.ts:
    import Icons from 'unplugin-icons/vite'
    export default defineConfig({ plugins: [Icons({ /* options */ })] })
    
  4. Pick the right compiler option for the framework: vue3, vue-vapor, jsx with jsx: 'react', solid, svelte, astro, qwik, or ember.
  5. Import icons with the ~icons/{collection}/{icon} pattern and use them as components:
    import IconAccessibility from '~icons/carbon/accessibility'
    
    They accept standard style and class props, so font-size and color work as expected.
  6. For local SVGs, point FileSystemIconLoader or FileSystemHMRIconLoader at a folder; for third-party packages, use ExternalPackageIconLoader.

Documented limitations to keep in mind: v24+ requires Node 20, the package is ESM-only (use .mjs configs for Webpack, Next.js, and Vue CLI), and with Next.js you must add the .jsx extension on imports (for example ~icons/dashicons/arrow-right.jsx) to avoid a known resolution issue. For Vue Vapor, use compiler: 'vue-vapor' because the standard vue3 compiler emits virtual-DOM components that render as nothing in a Vapor app. HMR for file-system icons only fires when the SVG folder lives inside the project root. Per-tool working setups are available in the repository's examples/ directory.