GitHub

NPM version

Access thousands of icons as components on-demand universally.

Features

  • ๐ŸŒ Universal
    • ๐Ÿคน Any icon sets - ~150 popular sets with over 200,000 icons, logos, emojis, etc. Powered by Iconify.
    • ๐Ÿ“ฆ Major build tools - Vite, Webpack, Rollup, Nuxt, Rspack, etc. Powered by unplugin.
    • ๐Ÿš€ Major frameworks - Vanilla, Web Components, React, Vue 3, Solid, Svelte, and more. Contribute.
    • ๐Ÿฑ Any combinations of them!
  • โ˜๏ธ On-demand - Only bundle the icons you really use, while having all the options.
  • ๐Ÿ–จ SSR / SSG friendly - Ship the icons with your page, no more FOUC.
  • ๐ŸŒˆ Stylable - Change size, color, or even add animations as you would with styles and classes.
  • ๐Ÿ“ฅ Custom icons - load your custom icons to get universal integrations at ease.
  • ๐Ÿ“ฒ Auto Importing - Use icons as components directly in your template.
  • ๐Ÿฆพ TypeScript support.
  • ๐Ÿ” Browse Icons

vite-plugin-icons has been renamed to unplugin-icons, see the migration guide

Quick Start

Basic Usage

Import icons using the convention ~icons/{collection}/{icon} and use them as components. Auto importing is also supported.

React Example:

import IconAccessibility from '~icons/carbon/accessibility'
import IconAccountBox from '~icons/mdi/account-box'
function App() {
  return (
    <div>
      <IconAccessibility />
      <IconAccountBox style={{ fontSize: '2em', color: 'red' }} />
    </div>
  )
}

Vue Example:

<script setup>
import IconAccessibility from '~icons/carbon/accessibility'
import IconAccountBox from '~icons/mdi/account-box'
</script>
<template>
  <icon-accessibility />
  <icon-account-box style="font-size: 2em; color: red" />
</template>

Installation

Note: This package is ESM-only. Make sure your project uses ES modules ("type": "module" in package.json or .mjs file extensions).

Step 1: Install the Plugin

npm i -D unplugin-icons

Step 2: Install Icon Data

We use Iconify as the icons data source (supports 100+ icon sets).

Tip

โœจ VS Code Users: Install the Iconify IntelliSense extension for inlay preview, auto-completion, and hover information.

Option A: Install Full Collection (Recommended for flexibility)

npm i -D @iconify/json

This installs all icon sets (~120MB). Only icons you actually use will be bundled in production.

Option B: Install Individual Icon Sets

Install only the icon sets you need:

npm i -D @iconify-json/mdi @iconify-json/carbon

Option C: Auto Install (Experimental)

Let unplugin-icons automatically install icon sets when you import them:

Icons({
  autoInstall: true, // Auto-detects npm/yarn/pnpm
})

Examples

Check out the playgrounds page to try examples online in StackBlitz.

Available examples:

Configuration

This section covers how to configure unplugin-icons for different build tools and frameworks.

Build Tools

Vite
// vite.config.ts
import Icons from 'unplugin-icons/vite'
export default defineConfig({
  plugins: [
    Icons({ /* options */ }),
  ],
})
Rollup
// rollup.config.js
import Icons from 'unplugin-icons/rollup'
export default {
  plugins: [
    Icons({ /* options */ }),
  ],
}
Webpack
// webpack.config.mjs
import Icons from 'unplugin-icons/webpack'
export default {
  /* ... */
  plugins: [
    Icons({ /* options */ }),
  ],
}
Nuxt

Nuxt 2 and Nuxt Bridge

// nuxt.config.ts
export default {
  buildModules: [
    ['unplugin-icons/nuxt', { /* options */ }],
  ],
}

Nuxt 3/4

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    ['unplugin-icons/nuxt', { /* options */ }]
  ],
})

Or work with unplugin-vue-components resolvers

import IconsResolver from 'unplugin-icons/resolver'
import ViteComponents from 'unplugin-vue-components/vite'
// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    'unplugin-icons/nuxt',
  ],
  vite: {
    plugins: [
      ViteComponents({
        resolvers: [
          IconsResolver({/* options */}),
        ],
      }),
    ],
  },
})

See the Nuxt example for a working example project.

Rspack
import Icons from 'unplugin-icons/rspack'
// rspack.config.mjs
export default defineConfig({
  plugins: [
    // ...
    Icons({/* options */}),
  ]
})
Vue CLI

Note: This package is ESM-only. You need to use vue.config.mjs with ES module syntax (requires @vue/cli-service ^5.0.8).

// vue.config.mjs
import Icons from 'unplugin-icons/webpack'
export default {
  configureWebpack: {
    plugins: [
      Icons({ /* options */ }),
    ],
  },
}
SvelteKit

Add to your vite.config.ts:

import { sveltekit } from '@sveltejs/kit/vite'
import Icons from 'unplugin-icons/vite'
import { defineConfig } from 'vite'
export default defineConfig({
  plugins: [
    sveltekit(),
    Icons({
      compiler: 'svelte',
    })
  ]
})

Check instructions in the Frameworks -> Svelte section below if you faced module import errors.

See the SvelteKit example for a working example project.

Svelte + Vite

Svelte support requires the @sveltejs/vite-plugin-svelte plugin:

npm i -D @sveltejs/vite-plugin-svelte

Add to your vite.config.ts:

import { svelte } from '@sveltejs/vite-plugin-svelte'
import Icons from 'unplugin-icons/vite'
import { defineConfig } from 'vite'
export default defineConfig({
  plugins: [
    svelte(),
    Icons({
      compiler: 'svelte',
    }),
  ],
})

Check instructions in the Frameworks -> Svelte section below if you faced module import errors.

See the Svelte + Vite example for a working example project.

Next.js

Note: This package is ESM-only. You need to use next.config.mjs with ES module syntax.

Add to your next.config.mjs:

// next.config.mjs
import Icons from 'unplugin-icons/webpack'
/** @type {import('next').NextConfig} */
export default {
  reactStrictMode: true,
  webpack(config) {
    config.plugins.push(
      Icons({
        compiler: 'jsx',
        jsx: 'react'
      })
    )
    return config
  }
}

Check instructions in the Frameworks -> React section below if you faced module import errors.

โš ๏ธ Warning: to import an icon is necessary to explicitly add the .jsx extension to the import path, so that Next.js knows how to load it, by example:

import IconArrowRight from '~icons/dashicons/arrow-right.jsx';
                                                     // ^-- write `.jsx` to avoid
                                                     // https://github.com/antfu/unplugin-icons/issues/103
// ...some code later
<IconArrowRight />

See the Next.js example for a working example project.

esbuild
// esbuild.config.js
import { build } from 'esbuild'
import Icons from 'unplugin-icons/esbuild'
build({
  /* ... */
  plugins: [
    Icons({
      /* options */
    }),
  ],
})
Astro
// astro.config.mjs
import { defineConfig } from 'astro/config'
import Icons from 'unplugin-icons/vite'
// https://astro.build/config
export default defineConfig({
  vite: {
    plugins: [
      Icons({
        compiler: 'astro',
      }),
    ],
  },
})

See the Astro example for a working example project.

Astro + Vue

Required @astrojs/vue installed.

import Vue from '@astrojs/vue'
// astro.config.mjs
import { defineConfig } from 'astro/config'
import Icons from 'unplugin-icons/vite'
// https://astro.build/config
export default defineConfig({
  integrations: [
    Vue(),
  ],
  vite: {
    plugins: [
      Icons({
        compiler: 'vue3',
      }),
    ],
  },
})

See the Astro + Vue example for a working example project.

Frameworks

Configure the compiler option based on your framework. Some frameworks may require additional peer dependencies.

Vue 3

Configuration:

Icons({ compiler: 'vue3' })

Peer Dependency:

Note: As of Vue 3.2.13+, @vue/compiler-sfc is included in the main vue package, so no additional installation is needed.

If you're using an older version:

npm i -D @vue/compiler-sfc

TypeScript Support:

Add to your tsconfig.json:

See the Vue 3 example for a complete setup.

React

Configuration:

Icons({ compiler: 'jsx', jsx: 'react' })

Peer Dependencies:

npm i -D @svgr/core @svgr/plugin-jsx

TypeScript Support:

Add to your tsconfig.json:

See the React example for a complete setup.

Preact

Configuration:

Icons({ compiler: 'jsx', jsx: 'preact' })

Peer Dependencies:

npm i -D @svgr/core @svgr/plugin-jsx

TypeScript Support:

Add to your tsconfig.json:

See the Preact example for a complete setup.

Solid

Configuration:

Icons({ compiler: 'solid' })

TypeScript Support:

Add to your tsconfig.json:

See the Solid example for a complete setup.

Svelte

Configuration:

Icons({ compiler: 'svelte' })

TypeScript Support:

For SvelteKit, add to src/app.d.ts:

import 'unplugin-icons/types/svelte'

For Svelte + Vite, add to src/vite-env.d.ts:

/// <reference types="svelte" />
/// <reference types="vite/client" />
/// <reference types="unplugin-icons/types/svelte" />

For Svelte 4, use:

/// <reference types="unplugin-icons/types/svelte4" />

For Svelte 3, use:

/// <reference types="unplugin-icons/types/svelte3" />

See the Svelte example for a complete setup.

Astro

Configuration:

Icons({ compiler: 'astro' })

TypeScript Support:

Add to your tsconfig.json:

See the Astro example for a complete setup.

Astro + Vue

Configuration:

Icons({ compiler: 'vue3' })

Requirements:

Requires @astrojs/vue to be installed.

TypeScript Support:

Add to your tsconfig.json:

See the Astro + Vue example for a complete setup.

Qwik

Option 1: Native Qwik Compiler (Recommended)

Configuration:

Icons({ compiler: 'qwik' })

Peer Dependency:

npm i -D @svgx/core

Option 2: JSX Compiler

Configuration:

Icons({ compiler: 'jsx', jsx: 'qwik' })

Peer Dependencies:

npm i -D @svgr/core @svgr/plugin-jsx

TypeScript Support:

Add to your tsconfig.json:

See the Qwik example for a complete setup.

Ember

Configuration:

Icons({ compiler: 'ember' })

Build Tool Support:

Ember works with either Webpack or Vite.

For Vite applications, add to vite.config.mjs:

import { ember, extensions } from '@embroider/vite'
import { babel } from '@rollup/plugin-babel'
import Icons from 'unplugin-icons/vite'
import { defineConfig } from 'vite'
export default defineConfig({
  plugins: [
    ember(),
    Icons({
      compiler: 'ember',
    }),
    babel({
      babelHelpers: 'runtime',
      extensions,
    }),
  ],
})

TypeScript Support:

Add to your tsconfig.json:

Ember + Webpack

Assuming your app was generated with --embroider, or manually migrated to embroider following the instructions on the old embroider readme

Add the Icon plugin to the webpack plugins array in ember-cli-build.js:

import { compatBuild } from '@embroider/compat'
import Icons from 'unplugin-icons/webpack'
return compatBuild(app, Webpack, {
    packagerOptions: {
      webpackConfig: {
        plugins: [
          Icons({
            compiler: 'ember',
          }),
        ],
      },
    },
    // ...other options

See the Ember (with Webpack) or Ember vite example for a working example project.

Raw SVG Import

Available from v0.13.2+

Import icons as raw SVG strings by adding ?raw to the import path. Useful for embedding SVG directly in HTML templates.

Example (Vue 3):

<script setup lang='ts'>
import RawMdiAlarmOff from '~icons/mdi/alarm-off?raw&width=4em&height=4em'
import RawMdiAlarmOff2 from '~icons/mdi/alarm-off?raw&width=1em&height=1em'
</script>
<template>
  <!-- raw example -->
  <pre>
    import RawMdiAlarmOff from '~icons/mdi/alarm-off?raw&width=4em&height=4em'
    {{ RawMdiAlarmOff }}
    import RawMdiAlarmOff2 from '~icons/mdi/alarm-off?raw&width=1em&height=1em'
    {{ RawMdiAlarmOff2 }}
  </pre>
  <!-- svg example -->
  <span v-html="RawMdiAlarmOff" />
  <span v-html="RawMdiAlarmOff2" />
</template>

Custom Icons

Load your own custom icons and use them with the same universal API.

"import { promises as fs } from 'node:fs' // loader helpers import { FileSystemIconLoader } from 'unplugin-icons/loaders' Icons({ customCollections: { // key as the collection name 'my-icons': { account: ' ', // load your custom icon lazily settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'), /* ... */ }, 'my-other-icons': async (iconName) => { // your custom loader here. Do whatever you want. // for example, fetch from a remote server: return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text()) }, // a helper to load icons from the file system // files under `./assets/icons` with `.svg` extension will be loaded as it's file name // you can also provide a transform callback to change each icon (optional) 'my-yet-other-icons': FileSystemIconLoader( './assets/icons', svg => svg.replace(/^ ', // load your custom icon lazily settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'), /* ... */ }, 'my-other-icons': async (iconName) => { // your custom loader here. Do whatever you want. // for example, fetch from a remote server: return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text()) }, // a helper to load icons from the file system // files under `./assets/icons` with `.svg` extension will be loaded as it's file name // you can also provide a transform callback to change each icon (optional) 'my-yet-other-icons': FileSystemIconLoader( './assets/icons', svg => svg.replace(/^ ', /* ... */ }, }, transform(svg, collection, icon) { // apply fill to this icon on this collection if (collection === 'my-icons' && icon === 'account') return svg.replace(/^

Read the original on github.com โ†—