Vite plugin that auto-detects and bundles only the Ionic icons your project uses — icon tree-shaking with zero config.
When using @ionic/core with Vite, the full icon set (~1 300 SVG files) would normally be served or copied entirely. This plugin solves that in two ways:
node_modules. No copying.<ion-icon name="..."> usage and only those icons are emitted as build assets.Supports all major frameworks: React, Vue, Angular, Svelte, Mithril, Preact, SolidJS, plain HTML.
npm install -D vite-plugin-ionic-icons
Peer dependency:
vite >= 4.0.0
Requires@ionic/coreto be installed (it provides the SVG files).
// vite.config.ts
import { defineConfig } from 'vite';
import ionicIcons from 'vite-plugin-ionic-icons';
export default defineConfig({
plugins: [
ionicIcons(),
],
});
That's it. Icons are served from /svg/<name>.svg in dev and emitted to svg/ in your build output.
ionicIcons({
// Source directory (or array of directories) to scan for icon usage.
// Default: './src'
srcDir: './src',
// Extra file extensions to include in the scan.
// Default: ['.js', '.ts', '.jsx', '.tsx', '.html', '.vue', '.svelte']
extensions: ['.js', '.ts', '.jsx', '.tsx', '.html', '.vue', '.svelte'],
// Icon names to always include, even if not found in source files.
// Useful for icons loaded dynamically at runtime.
// Default: []
extraIcons: ['warning-outline', 'help-circle'],
// Path to the directory containing Ionic's SVG files.
// Default: 'node_modules/@ionic/core/dist/ionic/svg'
iconSrcDir: 'node_modules/@ionic/core/dist/ionic/svg',
// Sub-directory name used for serving / emitting icons.
// Default: 'svg'
iconDestDir: 'svg',
// Log detected icons and emit count.
// Default: false
verbose: true,
})
The plugin detects static icon names across all common syntaxes.
<ion-icon name="add-outline" />
<ion-icon name="trash" size="small" />
<!-- static -->
<ion-icon name="add-outline" />
<!-- string literal in dynamic binding -->
<ion-icon :name="'add-outline'" />
Dynamic bindings like
:name="myVar"cannot be resolved at build time. UseextraIconsto add them manually.
<!-- static -->
<ion-icon name="add-outline"></ion-icon>
<!-- string literal in property binding -->
<ion-icon [name]="'add-outline'"></ion-icon>
<ion-icon name="add-outline" />
m('ion-icon', { name: 'add-outline' })
m("ion-icon", { name: "trash", size: "small" })
h('ion-icon', { name: 'add-outline' })
<ion-icon name="add-outline"></ion-icon>
If you resolve icon names at runtime (e.g. from an API or a config object), the scanner cannot detect them. Add them with extraIcons:
ionicIcons({
extraIcons: ['warning-outline', 'checkmark-circle', 'close-circle'],
})
Build time
└── generateBundle()
├── scan srcDir recursively
├── apply 7 regex patterns (one per framework)
├── deduplicate icon names
└── emitFile() for each used icon → dist/svg/<name>.svg
Dev time
└── configureServer()
└── middleware: GET /svg/<name>.svg
└── pipe from node_modules/@ionic/core/dist/ionic/svg/<name>.svg
MIT © Dominic Jean