npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

iconify-static

v0.1.2

Published

Offline-first Iconify icons

Downloads

206

Readme

iconify-static

Offline-first Iconify icons for Svelte and web components. Icons are downloaded at build time and served from your static assets, instead of an external CDN.

This project aims to be a drop-in replacement for the existing Iconify library.

Features

  • Icons stored locally in your static/ directory; no runtime dependency on Iconify CDN
  • Automatic icon detection from source code
  • Vite plugin downloads new icons at build time
  • Works with Svelte components and vanilla web components

Installation

Step 1: Install the package

npm install iconify-static

Step 2: Configure Vite

Add the plugin to your vite.config.ts:

import { sveltekit } from '@sveltejs/kit/vite';
import { iconifyStatic } from 'iconify-static/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    sveltekit(), // Only required for sveltekit; you don't need this if you're using web components
    iconifyStatic()
  ]
});

Step 3: Use icons in your components

Svelte component:

<script>
  import { Icon } from 'iconify-static';
</script>

<Icon icon="mdi:home" />

Web component:

<script>
  import { registerIconifyStatic } from 'iconify-static';
  registerIconifyStatic();
</script>

<iconify-icon icon="mdi:home"></iconify-icon>

Step 4: Build or run via Vite

Build or run with your usual command, e.g.

npm run dev
npm run build

The plugin automatically detects icons used in your code and downloads them to static/_icons/.

Usage Examples

Svelte Component

<script>
  import { Icon } from 'iconify-static';
</script>

<!-- Basic usage -->
<Icon icon="mdi:home" />

<!-- With size -->
<Icon icon="mdi:star" width="32" />
<Icon icon="mdi:star" width="2em" />

<!-- With color -->
<Icon icon="mdi:heart" color="red" />
<Icon icon="mdi:heart" color="#ff6600" />

<!-- Inline with text -->
<p>Click the <Icon icon="mdi:menu" inline /> icon to...</p>

<!-- Transformations -->
<Icon icon="mdi:arrow-right" hFlip />
<Icon icon="mdi:arrow-right" vFlip />
<Icon icon="mdi:arrow-right" rotate={1} />
<Icon icon="mdi:arrow-right" rotate="45deg" />

<!-- Multiple icon sets -->
<Icon icon="ph:house" />
<Icon icon="carbon:home" />
<Icon icon="lucide:home" />
<Icon icon="tabler:home" />

Web Component

<!-- Basic usage -->
<iconify-icon icon="mdi:home"></iconify-icon>

<!-- With size -->
<iconify-icon icon="mdi:star" width="32"></iconify-icon>

<!-- With color -->
<iconify-icon icon="mdi:heart" color="red"></iconify-icon>

<!-- Inline with text -->
<p>Click the <iconify-icon icon="mdi:menu" inline></iconify-icon> icon to...</p>

<!-- Transformations -->
<iconify-icon icon="mdi:arrow-right" flip="horizontal"></iconify-icon>
<iconify-icon icon="mdi:arrow-right" rotate="1"></iconify-icon>

Props

Svelte Component Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | icon | string | required | Icon name in "prefix:name" format (e.g., "mdi:home") | | width | string \| number | "1em" | Icon width (number or CSS unit) | | height | string \| number | width | Icon height (defaults to width) | | color | string | - | Icon color (any CSS color value) | | inline | boolean | false | Align icon with text baseline | | hFlip | boolean | false | Flip icon horizontally | | vFlip | boolean | false | Flip icon vertically | | flip | string | - | "horizontal", "vertical", or "horizontal,vertical" | | rotate | number \| string | - | Rotation: 0-3 for 90deg increments, or CSS angle like "45deg" | | onLoad | function | - | Callback when icon SVG loads |

Web Component Attributes

| Attribute | Type | Default | Description | |-----------|------|---------|-------------| | icon | string | required | Icon name in "prefix:name" format | | width | string | "1em" | Icon width | | height | string | width | Icon height | | color | string | - | Icon color | | inline | (boolean attr) | - | Align icon with text baseline | | flip | string | - | "horizontal", "vertical", or "horizontal,vertical" | | rotate | string | - | Rotation: "0"-"3" for 90deg increments, or "45deg" |

Plugin Configuration

iconifyStatic({
  // Directory where icons are saved (default: 'static/_icons')
  iconsDir: 'static/_icons',

  // Directory to scan for icon usage (default: 'src')
  sourceDir: 'src',

  // Remove unused icons from iconsDir (default: true)
  cleanup: true,

  // Log download/removal activity (default: false)
  verbose: false,

  // Scan for icons in all strings across your files  with these prefixes (default: [])
  scanPrefixes: ['mdi', 'carbon'],
})

Icon Detection

By default, the plugin detects icons used in the icon prop:

<Icon icon="mdi:home" />        <!-- Detected -->
<Icon icon='carbon:search' />   <!-- Detected -->
<Icon icon={`lucide:check`} />  <!-- Detected -->

Detecting Icons in Constants/Variables

For icons stored in constants or variables, use the scanPrefixes option:

// vite.config.ts
iconifyStatic({
  scanPrefixes: ['mdi', 'carbon']
})

This scans for any string matching "{prefix}:{name}" anywhere in your code:

// All of these are now detected when scanPrefixes includes 'mdi':
const HOME_ICON = 'mdi:home';
const icons = { settings: 'mdi:cog', user: 'mdi:account' };
const list = ['mdi:star', 'mdi:heart'];

Preserving Unused Icons

By default, icons not found in source code are deleted. To preserve all icons:

iconifyStatic({
  cleanup: false
})

Deploying to a Subpath (GitHub Pages, etc.)

When deploying to a subpath (e.g., https://username.github.io/repo-name/), configure Vite's base option so icons are fetched from the correct URL.

SvelteKit (svelte.config.js):

const dev = process.argv.includes("dev");

export default {
  kit: {
    paths: {
      base: dev ? "" : "/repo-name",
    },
  },
};

Plain Vite (vite.config.ts):

export default defineConfig({
  base: process.env.NODE_ENV === "production" ? "/repo-name" : "/",
  plugins: [iconifyStatic()],
});

Limitations

scanPrefixes limitations

The scanPrefixes option only detects string literals. These patterns are not detected:

// NOT detected - runtime concatenation
const prefix = 'mdi';
const icon = prefix + ':home';

// NOT detected - template literal with variable
const name = 'home';
const icon = `mdi:${name}`;

// NOT detected - dynamic from API/database
const icon = await fetchIconName();

For truly dynamic icons, either:

  1. Ensure all possible icons are referenced as string literals somewhere in code
  2. Use cleanup: false and manually manage icons in static/_icons/

False positives

scanPrefixes may detect strings that look like icons but aren't:

// This would be detected if scanPrefixes includes 'mdi'
const notAnIcon = 'mdi:this-is-not-real';

This results in a build error if the icon doesn't exist.

Supported Icon Sets

Any icon set available on Iconify works:

  • mdi - Material Design Icons
  • carbon - IBM Carbon
  • lucide - Lucide
  • tabler - Tabler Icons
  • ph - Phosphor Icons
  • fluent - Fluent UI Icons
  • And many more...

Contributing & Raising Issues

Please feel free to raise issues for bugs or feature requests, but refrain from using AI to write them.

This project aims to be a drop-in replacement for Iconify's Svelte components, but may not be perfect; any differences are bugs, and detailed reports are appreciated.

PRs for fixes and improvements are welcomed, but I recommend raising an issue first if possible. AI generated changes may be accepted, but please make sure to validate, test, and check them for quality before raising a PR.

Support

Please make sure to support the Iconify team and the designers who make the icons you use!

License

MIT