UNPKG

13.8 kBMarkdownView Raw
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
5Access 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&nbsp;&nbsp;&nbsp;๐Ÿ’ก **Story beind this tool**: [Journey with Icons Continues](https://antfu.me/posts/journey-with-icons-continues) - a blog post by Anthony&nbsp;&nbsp;&nbsp;
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
32Import 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
37import IconAccessibility from '~icons/carbon/accessibility'
38import IconAccountBox from '~icons/mdi/account-box'
39
40function 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>
54import IconAccessibility from '~icons/carbon/accessibility'
55import 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
69npm i -D unplugin-icons
70```
71
72### Icons Data
73
74We use [Iconify](https://iconify.design/) as the icons data source (supports 100+ iconsets).
75
76You have two ways to install them:
77
78###### Install Full Collection
79
80```bash
81npm 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
88If 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]`.
89For example, to install [Material Design Icons](), you can do:
90
91```bash
92npm i -D @iconify-json/mdi
93```
94
95To boost your workflow, it's also possible to let `unplugin-icons` handle that installation by enabling the `autoInstall` option.
96
97```ts
98Icons({
99 // expiremental
100 autoInstall: true
101})
102```
103
104It 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
115import Icons from 'unplugin-icons/vite'
116
117export 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
131import Icons from 'unplugin-icons/rollup'
132
133export 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
148module.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
163export 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
179module.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
195import preprocess from 'svelte-preprocess'
196import Icons from 'unplugin-icons/vite'
197
198/** @type {import('@sveltejs/kit').Config} */
199const 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
216export default config
217```
218
219<br></details>
220
221<details>
222<summary>Svelte + Vite</summary><br>
223
224Svelte support requires plugin dependency `@sveltejs/vite-plugin-svelte`:
225```shell
226npm i -D @sveltejs/vite-plugin-svelte
227```
228
229The `unplugin-icons` plugin should be configured on `vite.config.js` configuration file:
230
231```ts
232// vite.config.js
233import { defineConfig } from 'vite'
234import { svelte } from '@sveltejs/vite-plugin-svelte'
235import Icons from 'unplugin-icons/vite'
236
237export 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
255Vue 3 support requires peer dependency `@vue/compiler-sfc`:
256
257```bash
258npm i -D @vue/compiler-sfc
259```
260
261```ts
262Icons({ compiler: 'vue3' })
263```
264
265Type 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
284Vue 2 support requires peer dependency `vue-template-compiler`:
285
286```bash
287npm i -D vue-template-compiler
288```
289
290```ts
291Icons({ compiler: 'vue2' })
292```
293
294Type 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
312JSX support requires peer dependency `@svgr/core`:
313
314```bash
315npm i -D @svgr/core
316```
317
318```ts
319Icons({ compiler: 'jsx', jsx: 'react' })
320```
321
322Type 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
341JSX support requires peer dependency `@svgr/core`:
342
343```bash
344npm i -D @svgr/core
345```
346
347```ts
348Icons({ compiler: 'jsx', jsx: 'preact' })
349```
350
351Type 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
372Icons({ compiler: 'solid' })
373```
374
375Type 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
395Icons({ compiler: 'svelte' })
396```
397
398Type Declarations
399
400For Svelte Kit, on `src/global.d.ts` file:
401```html
402/// <reference types="@sveltejs/kit" />
403/// <reference types="unplugin-icons/types/svelte" />
404```
405
406For 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
417From v0.11, you can now load your own icons!
418
419```ts
420import { promises as fs } from 'fs'
421// loader helpers
422import { FileSystemIconLoader } from 'unplugin-icons/loaders'
423
424Icons({
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
445Then use as
446
447```ts
448import IconAccount from '~icons/my-icons/account'
449import IconFoo from '~icons/my-other-icons/foo'
450import 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
459When using with resolvers for auto-importing, you will need to tell it your custom collection names:
460
461```ts
462IconResolver({
463 customCollections: [
464 'my-icons',
465 'my-other-icons',
466 'my-yet-other-icons',
467 ]
468})
469```
470
471See 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
489import 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
494export 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
516You can set default styling for all icons.
517The following config shows the default values of each option:
518
519```ts
520Icons({
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
534Use with [`unplugin-vue-components`](https://github.com/antfu/unplugin-vue-components)
535
536For example in Vite:
537
538```js
539// vite.config.js
540import Vue from '@vitejs/plugin-vue'
541import Icons from 'unplugin-icons/vite'
542import IconsResolver from 'unplugin-icons/resolver'
543import Components from 'unplugin-vue-components/vite'
544
545export default {
546 plugins: [
547 Vue(),
548 Components({
549 resolvers: IconsResolver(),
550 }),
551 Icons(),
552 ],
553}
554```
555
556Then 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
570Use with [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import)
571
572For example in Vite:
573
574```js
575// vite.config.js
576import Icons from 'unplugin-icons/vite'
577import IconsResolver from 'unplugin-icons/resolver'
578import AutoImport from 'unplugin-auto-import/vite'
579
580export 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
598Then 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
601export 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
615When using component resolver, you have to follow the name conversion for icons to be properly inferred.
616
617```
618{prefix}-{collection}-{icon}
619```
620
621The `collection` field follows [Iconify's collection IDs](https://iconify.design/icon-sets/).
622
623By default, the prefix is set to `i` while you can customize via config
624
625```ts
626IconsResolver({
627 prefix: 'icon' // <--
628})
629```
630
631```html
632<template>
633 <icon-mdi-account />
634</template>
635```
636
637Non-prefix mode is also supported
638
639```ts
640IconsResolver({
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
655When using component resolver, you have to use the name of the collection that can be long or redundant: for example,
656when using `icon-park` collection you need to use it like this `<icon-icon-park-abnormal />`.
657
658You can add an alias for any collection to the `IconResolver` plugin:
659
660```ts
661IconsResolver({
662 alias: {
663 park: 'icon-park',
664 fas: 'fa-solid',
665 ...
666 }
667})
668```
669
670You can use the alias or the collection name, the plugin will resolve both.
671
672Following 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
677This 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
687MIT License ยฉ 2020-PRESENT [Anthony Fu](https://github.com/antfu)