1 | # unplugin-icons
|
2 |
|
3 | [![NPM version](https://img.shields.io/npm/v/unplugin-icons?color=a1b858&label=)](https://www.npmjs.com/package/unplugin-icons)
|
4 |
|
5 | Access thousands of icons as components **on-demand** universally.
|
6 |
|
7 | ### Features
|
8 |
|
9 | - ๐ Universal
|
10 | - ๐คน **Any** icon sets - 100+ popular sets with over 10,000 icons, logos, emojis, etc. Powered by [Iconify](https://github.com/iconify/iconify).
|
11 | - ๐ฆ **Major** build tools - Vite, Webpack, Rollup, Nuxt, etc. Powered by [unplugin](https://github.com/unjs/unplugin).
|
12 | - ๐ช **Major** frameworks - Vanilla, Web Components, React, Vue 3, Vue 2, Solid, Svelte, and more. [Contribute](./src/core/compiles).
|
13 | - ๐ฑ **Any** combinations of them!
|
14 | - โ๏ธ On-demand - Only bundle the icons you really uses, while having all the options.
|
15 | - ๐จ SSR / SSG friendly - Ship the icons with your page, no more FOUC.
|
16 | - ๐ Stylable - Change size, color, or even add animations as you would with styles and classes.
|
17 | - ๐ฅ [Custom icons](#custom-icons) - load your custom icons to get universal integrations at ease.
|
18 | - ๐ฒ [Auto Importing](#auto-importing) - Use icons as components directly in your template.
|
19 | - ๐ฆพ TypeScript support.
|
20 | - ๐ [Browse Icons](https://icones.js.org/)
|
21 |
|
22 | <table><td><br>
|
23 |
|
24 | ๐ก **Story beind this tool**: [Journey with Icons Continues](https://antfu.me/posts/journey-with-icons-continues) - a blog post by Anthony
|
25 |
|
26 | </td></table>
|
27 |
|
28 | > **`vite-plugin-icons` has been renamed to `unplugin-icons`**, see the [migration guide](#migrate-from-vite-plugin-icons)
|
29 |
|
30 | ## Usage
|
31 |
|
32 | Import icons names with the convension `~icons/{collection}/{icon}` and use them directly as components. [Auto importing is also possible](#auto-importing).
|
33 |
|
34 | ###### React
|
35 |
|
36 | ```jsx
|
37 | import IconAccessibility from '~icons/carbon/accessibility'
|
38 | import IconAccountBox from '~icons/mdi/account-box'
|
39 |
|
40 | function App() {
|
41 | return (
|
42 | <div>
|
43 | <IconAccessibility />
|
44 | <IconAccountBox style={{ fontSize: '2em', color: 'red' }}/>
|
45 | </div>
|
46 | )
|
47 | }
|
48 | ```
|
49 |
|
50 | ###### Vue
|
51 |
|
52 | ```html
|
53 | <script setup>
|
54 | import IconAccessibility from '~icons/carbon/accessibility'
|
55 | import IconAccountBox from '~icons/mdi/account-box'
|
56 | </script>
|
57 |
|
58 | <template>
|
59 | <icon-accessibility/>
|
60 | <icon-account-box style="font-size: 2em; color: red"/>
|
61 | </template>
|
62 | ```
|
63 |
|
64 | ## Install
|
65 |
|
66 | ### Plugin
|
67 |
|
68 | ```bash
|
69 | npm i -D unplugin-icons
|
70 | ```
|
71 |
|
72 | ### Icons Data
|
73 |
|
74 | We use [Iconify](https://iconify.design/) as the icons data source (supports 100+ iconsets).
|
75 |
|
76 | You have two ways to install them:
|
77 |
|
78 | ###### Install Full Collection
|
79 |
|
80 | ```bash
|
81 | npm i -D @iconify/json
|
82 | ```
|
83 |
|
84 | `@iconify/json` (~120MB) includes all the iconsets from Iconify so you can install once and use any of them as you want (only the icons you actually use will be bundle into the production build).
|
85 |
|
86 | ###### Install by Icon Set
|
87 |
|
88 | If you only want to use a few of the icon sets and don't want to download the entire collection, you can also install them individually with `@iconify-json/[collection-id]`.
|
89 | For example, to install [Material Design Icons](), you can do:
|
90 |
|
91 | ```bash
|
92 | npm i -D @iconify-json/mdi
|
93 | ```
|
94 |
|
95 | To boost your workflow, it's also possible to let `unplugin-icons` handle that installation by enabling the `autoInstall` option.
|
96 |
|
97 | ```ts
|
98 | Icons({
|
99 | // expiremental
|
100 | autoInstall: true
|
101 | })
|
102 | ```
|
103 |
|
104 | It will install the icon set when you import them. The right package manager will be auto-detected (`npm`, `yarn` or `pnpm`).
|
105 |
|
106 | ## Configuration
|
107 |
|
108 | ###### Build Tools
|
109 |
|
110 | <details>
|
111 | <summary>Vite</summary><br>
|
112 |
|
113 | ```ts
|
114 | // vite.config.ts
|
115 | import Icons from 'unplugin-icons/vite'
|
116 |
|
117 | export default defineConfig({
|
118 | plugins: [
|
119 | Icons({ /* options */ }),
|
120 | ],
|
121 | })
|
122 | ```
|
123 |
|
124 | <br></details>
|
125 |
|
126 | <details>
|
127 | <summary>Rollup</summary><br>
|
128 |
|
129 | ```ts
|
130 | // rollup.config.js
|
131 | import Icons from 'unplugin-icons/rollup'
|
132 |
|
133 | export default {
|
134 | plugins: [
|
135 | Icons({ /* options */ }),
|
136 | ],
|
137 | }
|
138 | ```
|
139 |
|
140 | <br></details>
|
141 |
|
142 |
|
143 | <details>
|
144 | <summary>Webpack</summary><br>
|
145 |
|
146 | ```ts
|
147 | // webpack.config.js
|
148 | module.exports = {
|
149 | /* ... */
|
150 | plugins: [
|
151 | require('unplugin-icons/webpack')({ /* options */ })
|
152 | ]
|
153 | }
|
154 | ```
|
155 |
|
156 | <br></details>
|
157 |
|
158 | <details>
|
159 | <summary>Nuxt</summary><br>
|
160 |
|
161 | ```ts
|
162 | // nuxt.config.js
|
163 | export default {
|
164 | buildModules: [
|
165 | ['unplugin-icons/nuxt', { /* options */ }],
|
166 | ],
|
167 | }
|
168 | ```
|
169 |
|
170 | > This module works for both Nuxt 2 and [Nuxt Vite](https://github.com/nuxt/vite)
|
171 |
|
172 | <br></details>
|
173 |
|
174 | <details>
|
175 | <summary>Vue CLI</summary><br>
|
176 |
|
177 | ```ts
|
178 | // vue.config.js
|
179 | module.exports = {
|
180 | configureWebpack: {
|
181 | plugins: [
|
182 | require('unplugin-icons/webpack')({ /* options */ }),
|
183 | ],
|
184 | },
|
185 | }
|
186 | ```
|
187 |
|
188 | <br></details>
|
189 |
|
190 | <details>
|
191 | <summary>Svelte Kit</summary><br>
|
192 |
|
193 | ```ts
|
194 | // svelte.config.js
|
195 | import preprocess from 'svelte-preprocess'
|
196 | import Icons from 'unplugin-icons/vite'
|
197 |
|
198 | /** @type {import('@sveltejs/kit').Config} */
|
199 | const config = {
|
200 | // Consult https://github.com/sveltejs/svelte-preprocess
|
201 | // for more information about preprocessors
|
202 | preprocess: preprocess(),
|
203 | kit: {
|
204 | // hydrate the <div id="svelte"> element in src/app.html
|
205 | target: '#svelte',
|
206 | vite: {
|
207 | plugins: [
|
208 | Icons({
|
209 | compiler: 'svelte',
|
210 | }),
|
211 | ],
|
212 | },
|
213 | },
|
214 | }
|
215 |
|
216 | export default config
|
217 | ```
|
218 |
|
219 | <br></details>
|
220 |
|
221 | <details>
|
222 | <summary>Svelte + Vite</summary><br>
|
223 |
|
224 | Svelte support requires plugin dependency `@sveltejs/vite-plugin-svelte`:
|
225 | ```shell
|
226 | npm i -D @sveltejs/vite-plugin-svelte
|
227 | ```
|
228 |
|
229 | The `unplugin-icons` plugin should be configured on `vite.config.js` configuration file:
|
230 |
|
231 | ```ts
|
232 | // vite.config.js
|
233 | import { defineConfig } from 'vite'
|
234 | import { svelte } from '@sveltejs/vite-plugin-svelte'
|
235 | import Icons from 'unplugin-icons/vite'
|
236 |
|
237 | export default defineConfig({
|
238 | plugins: [
|
239 | svelte(),
|
240 | Icons({
|
241 | compiler: 'svelte',
|
242 | }),
|
243 | ],
|
244 | })
|
245 | ```
|
246 |
|
247 | <br></details>
|
248 |
|
249 | ###### Frameworks
|
250 |
|
251 |
|
252 | <details>
|
253 | <summary>Vue 3</summary><br>
|
254 |
|
255 | Vue 3 support requires peer dependency `@vue/compiler-sfc`:
|
256 |
|
257 | ```bash
|
258 | npm i -D @vue/compiler-sfc
|
259 | ```
|
260 |
|
261 | ```ts
|
262 | Icons({ compiler: 'vue3' })
|
263 | ```
|
264 |
|
265 | Type Declarations
|
266 |
|
267 | ```jsonc
|
268 | // tsconfig.json
|
269 | {
|
270 | "compilerOptions": {
|
271 | "types": [
|
272 | "unplugin-icons/types/vue",
|
273 | ]
|
274 | }
|
275 | }
|
276 | ```
|
277 |
|
278 | <br></details>
|
279 |
|
280 |
|
281 | <details>
|
282 | <summary>Vue 2</summary><br>
|
283 |
|
284 | Vue 2 support requires peer dependency `vue-template-compiler`:
|
285 |
|
286 | ```bash
|
287 | npm i -D vue-template-compiler
|
288 | ```
|
289 |
|
290 | ```ts
|
291 | Icons({ compiler: 'vue2' })
|
292 | ```
|
293 |
|
294 | Type Declarations
|
295 |
|
296 | ```jsonc
|
297 | // tsconfig.json
|
298 | {
|
299 | "compilerOptions": {
|
300 | "types": [
|
301 | "unplugin-icons/types/vue",
|
302 | ]
|
303 | }
|
304 | }
|
305 | ```
|
306 |
|
307 | <br></details>
|
308 |
|
309 | <details>
|
310 | <summary>React</summary><br>
|
311 |
|
312 | JSX support requires peer dependency `@svgr/core`:
|
313 |
|
314 | ```bash
|
315 | npm i -D @svgr/core
|
316 | ```
|
317 |
|
318 | ```ts
|
319 | Icons({ compiler: 'jsx', jsx: 'react' })
|
320 | ```
|
321 |
|
322 | Type Declarations
|
323 |
|
324 | ```jsonc
|
325 | // tsconfig.json
|
326 | {
|
327 | "compilerOptions": {
|
328 | "types": [
|
329 | "unplugin-icons/types/react",
|
330 | ]
|
331 | }
|
332 | }
|
333 | ```
|
334 |
|
335 | <br></details>
|
336 |
|
337 |
|
338 | <details>
|
339 | <summary>Preact</summary><br>
|
340 |
|
341 | JSX support requires peer dependency `@svgr/core`:
|
342 |
|
343 | ```bash
|
344 | npm i -D @svgr/core
|
345 | ```
|
346 |
|
347 | ```ts
|
348 | Icons({ compiler: 'jsx', jsx: 'preact' })
|
349 | ```
|
350 |
|
351 | Type Declarations
|
352 |
|
353 | ```jsonc
|
354 | // tsconfig.json
|
355 | {
|
356 | "compilerOptions": {
|
357 | "types": [
|
358 | "unplugin-icons/types/preact",
|
359 | ]
|
360 | }
|
361 | }
|
362 | ```
|
363 |
|
364 | <br></details>
|
365 |
|
366 |
|
367 | <details>
|
368 | <summary>Solid</summary><br>
|
369 |
|
370 |
|
371 | ```ts
|
372 | Icons({ compiler: 'solid' })
|
373 | ```
|
374 |
|
375 | Type Declarations
|
376 |
|
377 | ```jsonc
|
378 | // tsconfig.json
|
379 | {
|
380 | "compilerOptions": {
|
381 | "types": [
|
382 | "unplugin-icons/types/solid",
|
383 | ]
|
384 | }
|
385 | }
|
386 | ```
|
387 |
|
388 | <br></details>
|
389 |
|
390 | <details>
|
391 | <summary>Svelte</summary><br>
|
392 |
|
393 |
|
394 | ```ts
|
395 | Icons({ compiler: 'svelte' })
|
396 | ```
|
397 |
|
398 | Type Declarations
|
399 |
|
400 | For Svelte Kit, on `src/global.d.ts` file:
|
401 | ```html
|
402 | /// <reference types="@sveltejs/kit" />
|
403 | /// <reference types="unplugin-icons/types/svelte" />
|
404 | ```
|
405 |
|
406 | For Svelte + Vite, on `src/vite-env.d.ts` file:
|
407 | ```html
|
408 | /// <reference types="svelte" />
|
409 | /// <reference types="vite/client" />
|
410 | /// <reference types="unplugin-icons/types/svelte" />
|
411 | ```
|
412 |
|
413 | <br></details>
|
414 |
|
415 | ## Custom Icons
|
416 |
|
417 | From v0.11, you can now load your own icons!
|
418 |
|
419 | ```ts
|
420 | import { promises as fs } from 'fs'
|
421 | // loader helpers
|
422 | import { FileSystemIconLoader } from 'unplugin-icons/loaders'
|
423 |
|
424 | Icons({
|
425 | customCollections: {
|
426 | // key as the collection name
|
427 | 'my-icons': {
|
428 | 'account': '<svg><!-- ... --></svg>',
|
429 | // load your custom icon lazily
|
430 | 'settings': () => fs.readFile('./path/to/my-icon.svg', 'utf-8'),
|
431 | /* ... */
|
432 | },
|
433 | 'my-other-icons': async (iconName) => {
|
434 | // your custom loader here. Do whatever you want.
|
435 | // for example, fetch from a remote server:
|
436 | return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text())
|
437 | },
|
438 | // a helper to load icons from the file system
|
439 | // files under `./assets/icons` with `.svg` extension will be loaded as it's file name
|
440 | 'my-yet-other-icons': FileSystemIconLoader('./assets/icons'),
|
441 | }
|
442 | })
|
443 | ```
|
444 |
|
445 | Then use as
|
446 |
|
447 | ```ts
|
448 | import IconAccount from '~icons/my-icons/account'
|
449 | import IconFoo from '~icons/my-other-icons/foo'
|
450 | import IconBar from '~icons/my-yet-other-icons/bar'
|
451 | ```
|
452 |
|
453 | > ๐ก SVG Authoring Tips:
|
454 | > - To make your icons color adaptable, set `fill="currentColor"` for `stroke="currentColor"` in your SVG.
|
455 | > - Leave the `height` and `width` unspecified, we will set them for you.
|
456 |
|
457 | ### Use with Resolver
|
458 |
|
459 | When using with resolvers for auto-importing, you will need to tell it your custom collection names:
|
460 |
|
461 | ```ts
|
462 | IconResolver({
|
463 | customCollections: [
|
464 | 'my-icons',
|
465 | 'my-other-icons',
|
466 | 'my-yet-other-icons',
|
467 | ]
|
468 | })
|
469 | ```
|
470 |
|
471 | See the [Vue 3 + Vite example](./examples/vite-vue3/vite.config.ts).
|
472 |
|
473 | ## Migrate from `vite-plugin-icons`
|
474 |
|
475 | `package.json`
|
476 |
|
477 | ```diff
|
478 | {
|
479 | "devDependencies": {
|
480 | - "vite-plugin-icons": "*",
|
481 | + "unplugin-icons": "^0.7.0",
|
482 | }
|
483 | }
|
484 | ```
|
485 |
|
486 | `vite.config.json`
|
487 |
|
488 | ```diff
|
489 | import Components from 'unplugin-components/vite'
|
490 | - import Icons, { ViteIconsResolver } from 'vite-plugin-icons'
|
491 | + import Icons from 'unplugin-icons/vite'
|
492 | + import IconsResolver from 'unplugin-icons/resolver'
|
493 |
|
494 | export default {
|
495 | plugins: [
|
496 | Vue(),
|
497 | Components({
|
498 | resolvers: IconsResolver(),
|
499 | }),
|
500 | Icons(),
|
501 | ],
|
502 | }
|
503 | ```
|
504 |
|
505 | `*` - imports usage
|
506 |
|
507 | ```diff
|
508 | - import IconComponent from 'virtual:vite-icons/collection/name'
|
509 | + import IconComponent from '~icons/collection/name'
|
510 | ```
|
511 |
|
512 | > You can still use `virtual:icons` prefix in Vite if you prefer, but it's not yet supported in Webpack, we are unifying it as a workaround in the docs.
|
513 |
|
514 | ## Options
|
515 |
|
516 | You can set default styling for all icons.
|
517 | The following config shows the default values of each option:
|
518 |
|
519 | ```ts
|
520 | Icons({
|
521 | scale: 1.2, // Scale of icons against 1em
|
522 | defaultStyle: '', // Style apply to icons
|
523 | defaultClass: '', // Class names apply to icons
|
524 | compiler: null, // 'vue2', 'vue3', 'jsx'
|
525 | jsx: 'react' // 'react' or 'preact'
|
526 | })
|
527 | ```
|
528 |
|
529 | ## Auto Importing
|
530 |
|
531 | <details>
|
532 | <summary>Vue 2 & 3</summary><br>
|
533 |
|
534 | Use with [`unplugin-vue-components`](https://github.com/antfu/unplugin-vue-components)
|
535 |
|
536 | For example in Vite:
|
537 |
|
538 | ```js
|
539 | // vite.config.js
|
540 | import Vue from '@vitejs/plugin-vue'
|
541 | import Icons from 'unplugin-icons/vite'
|
542 | import IconsResolver from 'unplugin-icons/resolver'
|
543 | import Components from 'unplugin-vue-components/vite'
|
544 |
|
545 | export default {
|
546 | plugins: [
|
547 | Vue(),
|
548 | Components({
|
549 | resolvers: IconsResolver(),
|
550 | }),
|
551 | Icons(),
|
552 | ],
|
553 | }
|
554 | ```
|
555 |
|
556 | Then you can use any icons as you want without explicit importing. Only the used icons will be bundled.
|
557 |
|
558 | ```html
|
559 | <template>
|
560 | <i-carbon-accessibility/>
|
561 | <i-mdi-account-box style="font-size: 2em; color: red"/>
|
562 | </template>
|
563 | ```
|
564 |
|
565 | </details>
|
566 |
|
567 | <details>
|
568 | <summary>React & Solid</summary><br>
|
569 |
|
570 | Use with [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import)
|
571 |
|
572 | For example in Vite:
|
573 |
|
574 | ```js
|
575 | // vite.config.js
|
576 | import Icons from 'unplugin-icons/vite'
|
577 | import IconsResolver from 'unplugin-icons/resolver'
|
578 | import AutoImport from 'unplugin-auto-import/vite'
|
579 |
|
580 | export default {
|
581 | plugins: [
|
582 | /* ... */
|
583 | AutoImport({
|
584 | resolvers: [
|
585 | IconsResolver({
|
586 | prefix: 'Icon',
|
587 | extension: 'jsx'
|
588 | })
|
589 | ],
|
590 | }),
|
591 | Icons({
|
592 | compiler: 'jsx' // or 'solid'
|
593 | }),
|
594 | ],
|
595 | }
|
596 | ```
|
597 |
|
598 | Then you can use any icons with the prefix `Icon` as you want without explicit importing. Type declarations will be generated on the fly.
|
599 |
|
600 | ```js
|
601 | export function Component() {
|
602 | return (
|
603 | <div>
|
604 | <IconCarbonApps />
|
605 | <IconMdiAccountBox style="font-size: 2em; color: red"/>
|
606 | </div>
|
607 | )
|
608 | }
|
609 | ```
|
610 |
|
611 | </details>
|
612 |
|
613 | ### Name Conversion
|
614 |
|
615 | When using component resolver, you have to follow the name conversion for icons to be properly inferred.
|
616 |
|
617 | ```
|
618 | {prefix}-{collection}-{icon}
|
619 | ```
|
620 |
|
621 | The `collection` field follows [Iconify's collection IDs](https://iconify.design/icon-sets/).
|
622 |
|
623 | By default, the prefix is set to `i` while you can customize via config
|
624 |
|
625 | ```ts
|
626 | IconsResolver({
|
627 | prefix: 'icon' // <--
|
628 | })
|
629 | ```
|
630 |
|
631 | ```html
|
632 | <template>
|
633 | <icon-mdi-account />
|
634 | </template>
|
635 | ```
|
636 |
|
637 | Non-prefix mode is also supported
|
638 |
|
639 | ```ts
|
640 | IconsResolver({
|
641 | prefix: false, // <--
|
642 | // this is optional, default enabling all the collections supported by Iconify
|
643 | enabledCollections: ['mdi']
|
644 | })
|
645 | ```
|
646 |
|
647 | ```vue
|
648 | <template>
|
649 | <mdi-account />
|
650 | </template>
|
651 | ```
|
652 |
|
653 | ### Collection Aliases
|
654 |
|
655 | When using component resolver, you have to use the name of the collection that can be long or redundant: for example,
|
656 | when using `icon-park` collection you need to use it like this `<icon-icon-park-abnormal />`.
|
657 |
|
658 | You can add an alias for any collection to the `IconResolver` plugin:
|
659 |
|
660 | ```ts
|
661 | IconsResolver({
|
662 | alias: {
|
663 | park: 'icon-park',
|
664 | fas: 'fa-solid',
|
665 | ...
|
666 | }
|
667 | })
|
668 | ```
|
669 |
|
670 | You can use the alias or the collection name, the plugin will resolve both.
|
671 |
|
672 | Following with the example and configuring the plugin with previous `alias` entry, you can now use
|
673 | `<icon-park-abnormal />` or `<icon-icon-park-abnormal />`.
|
674 |
|
675 | ## Sponsors
|
676 |
|
677 | This project is part of my <a href='https://github.com/antfu-sponsors'>Sponsor Program</a>
|
678 |
|
679 | <p align="center">
|
680 | <a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg">
|
681 | <img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg'/>
|
682 | </a>
|
683 | </p>
|
684 |
|
685 | ## License
|
686 |
|
687 | MIT License ยฉ 2020-PRESENT [Anthony Fu](https://github.com/antfu)
|