Articles

index

title: Iconify blog

Iconify blog

Blog below contains major updates, migration guides and helpful articles related to Iconify project.

Iconify stuff

Animated icons

How to work with animated SVG:

Migration guides

Migration guides for major releases:

vendor-lock-in

title: Vendor lock-in and icons
replacements:
  - code: "60k"
    value: "${counters.icons-short}"
  - code: "70 icon sets"
    value: "${counters.sets} icon sets"

Vendor lock-in

What is vendor lock-in?

Vendor lock-in is when someone is essentially forced to continue using a product or service regardless of quality, because switching away from that product or service is not practical.

Icon sets

Most icon sets have their own icon components or fonts with stylesheets.

When using those components or fonts, you no longer have freedom to choose icons, you are only limited to icons provided by your chosen vendor.

Issues:

You are forced to choose bad icons or spend a lot of time.

Vendor lock-in with customisable software

Worst case of vendor lock-in, is when you are working with customisable software, who's authors made a choice to use a specific icon set or icon font. Very common cases are popular forum and blogging software packages.

Forums and blogging software have:

Unless you are designing theme only for yourself, as a theme designer you need to make sure it works with third party plug-ins. Third party plug-ins are designed to work with whatever default theme software package offers. So, even if you want to change icon set in your theme, you still need to keep default icon set or third party plugins might not work.

This very specific vendor lock-in is one of reasons why Iconify was created. After years of frustration of working with one very popular icon font, I wanted to find a solution to vendor lock-in for forum software, but at that moment there were none. See about Iconify.

Iconify

When using Iconify, doesn't it lock-in to Iconify?

Sort of, but it is a technology lock-in, not vendor lock-in and there are huge differences. See below.

Iconify was designed to be as flexible as possible, the only way you can get more freedom is directly embed SVG files one by one, without any specific icon set. Working with SVG is not easy for most developers and it is very time consuming.

Icons

One big difference is choice of icons. When using any icon set, you are limited to that icon set.

When using Iconify, you can use over 70 icon sets.

Custom icons

Most icon components support custom icon loaders, making it easy to use Iconify with custom icons.

Iconify also offers open source tools for cleaning up and optimising icons. Same tools that are used by Iconify scripts to keep icon sets up to date.

API

Some icon components get icon data from Iconify API. Doesn't that lock-in users to third party services?

No.

API is open source, you can host your own API, where you have full control over available icon sets and over servers.

Icon components can be easily configured to use your Iconify API servers. You can also build custom version of icon components that have your servers pre-configured.

Everything is open source!

Components

Icon data is available for everyone. You are not forced to use Iconify icon components.

Furthermore, third party icon components are very welcome... as long as it is high quality and maintained!

Freedom to choose

With Iconify you are free to do whatever you want.

Theme designers can choose from hundreds of thousands of icons or add their own icons, without worrying about compatibility with third party plug-ins.

index

title: How to add icon set to Iconify

How to add icon set to Iconify

If you have created an icon set, please consider sharing it with Iconify community.

Benefits

What are the benefits of publishing an icon set to Iconify?

Adding icon set

To add an icon set to Iconify, all you need to is open an issue on Iconify icon sets repository on GitHub.

In opened issue you need to post:

Icon set source

Icon sets are automatically updated several times a week. In order to update icon set, icons must be published and maintained by developer on one of the following sources:

Updates must be automated, so manually downloading icons from a third party website is not an option.

Open source

All icon sets must be open source and have a valid open source license.

If you are not sure about licenses, check out various icon sets. Click any icon set, it will show license and link to license text.

See Open Source Initiative for more licenses.

Bad icon sets

Not all icon sets are the same. There are good and bad icon sets. Bad icon sets are not accepted.

Most common reasons:

Design tips

If you are new to icon design, Google Material Icons website has excellent guidelines for designing icons.

Those guidelines are specific to material design, but the same principles apply to most icons. Even though icons are vector images, displays are pixel devices and icon edges are blurred if shape is not aligned to the edge of a pixel. Icon sets that follow a specific grid, have padding, shapes aligned to pixel edges, are the best looking icon sets.

cleanup

title: Cleaning up SVG code
functions:
  cleanupSVG: '/docs/libraries/tools/icon/cleanup.md'

Cleaning up SVG code

This article is part of SVG clean up article.

When a designer exports icon from an editor, often SVG contains a lot of extra code that is not needed to display an icon.

Bad icon example {#example}

The following SVG was generated with popular Inkscape software:

src: articles/el-cloud.svg

That code contains a lot of useless junk. If it is not used to display an icon, it is useless.

This is what is left of it after clean up:

src: articles/el-cloud.cleanup.svg

Icon is not yet finalised. It still requires optimisation.

If you think the code above contains just a little bit of useless tags, so it is not a big deal, it was a short example. There are icons in some icon sets with tens of kilobytes of junk data.

Process

Clean up process does not optimise the icon. It only does the following:

It is done with the [func]cleanupSVG() function from Iconify Tools.

Optimisation is done later, after parsing palette.

index

title: Cleaning up icons
types:
  IconifyJSON: '/docs/types/iconify-json.md'
functions:
  importDirectory: '/docs/libraries/tools/import/directory.md'
  forEach: '/docs/libraries/tools/icon-set/for-each.md'

Cleaning up icons

All icon sets available with Iconify pass validation and clean up process.

Why is it needed? SVG is not like other images, it can contain a lot of things, making it hard to work with.

Often icons contain a lot of useless code (especially when exported from old software).

Icons can even contain malicious code, such as scripts, event listeners and links to external resources.

When working with monotone icons (icons that have only one color, which supposed to be changeable), some icons use [attr]fill, some [attr]stroke, some rely on system default colors, some use [prop]black color, some use seemingly random colors.

All the tools you need are available in Iconify Tools package.

Process

Clean up process is done in 3 steps:

Validation and initial clean up {#cleanup}

First part is code validation and initial clean up.

When a designer exports an icon from an editor, often SVG contains a lot of extra code that is not needed to display an icon.

Icons can also contain dangerous elements, such as scripts or external resources. Icons are validated to make sure they do not contain anything other than vector shapes.

See example of bad code and explanation of how SVG validation works.

Palette changes {#palette}

After initial clean up and validation, the icon palette is changed.

For monotone icons, color is changed to [prop]currentColor to make sure the icon follows text color. This way it is easy to change color for any icon, regardless if the icon uses [prop]fill or [prop]stroke.

For icons with a hardcoded palette, the parser checks that the icon does not use system default colors or [prop]currentColor.

See article explaining palette changes.

Optimisation {#optimisation}

Last step is optimisation. It reduces icon size by removing unnecessary code and optimising paths.

See a very short article explaining icon optimisation.

Code

Want to try it with your icons? All functions you need are available in Iconify Tools.

Below are several examples.

Parsing one monotone icon

This code sample parses one monotone icon. Icon uses black color, which is replaced with [prop]currentColor, shapes with white color are removed.

Icon is loaded from one file, output is stored in another file.

src: libraries/tools/examples/cleanup-one-icon.ts

Parsing an entire icon set

This code sample parses an entire icon set and returns icon set in [type]IconifyJSON format.

It is similar to the example above, but uses [func]importDirectory() to import all SVG files in a directory, then stores the result in a JSON file. Each icon is parsed in asynchronous [func]forEach() callback.

src: libraries/tools/examples/cleanup-directory.ts

optimise

title: Optimising icon code
functions:
  deOptimisePaths: '/docs/libraries/tools/icon/paths.md'
  runSVGO: '/docs/libraries/tools/icon/svgo.md'

Optimising icon

This article is part of SVG clean up article.

After initial clean up and validation, changing icon palette, the icon is optimised.

Optimisation is done by SVGO. Not much to write about it, you can try SVGO optimisation yourself using SVGOMG project.

Code

Optimisation is done using [func]runSVGO() function from Iconify Tools, followed by [func]deOptimisePaths() to make sure icons are usable everywhere.

palette

title: Changing icon palette
functions:
  parseColors: '/docs/libraries/tools/icon/colors.md'

Changing icon palette

This article is part of SVG clean up article.

After initial clean up and validation, the icon palette is changed.

There can only be two types of icons:

Icons with palette {#palette}

Some icons have hardcoded palette:

include articles/icon-palette

Colors of these icons cannot be easily changed with a stylesheet.

When such icons are cleaned up, the parser verifies that the icon does not follow system default color (black color for [attr]fill) and does not contain [prop]currentColor.

Monotone icons {#monotone}

Most icons are monotone. They have only one color, which can be changed.

include articles/icon-monotone

When parsing monotone icons, color is changed to [prop]currentColor to make sure the icon follows text color. This way it is easy to change color for any icon, regardless if icon uses [prop]fill or [prop]stroke:

svg {
	color: red;
}

Parsing such icons is not easy. When icons are exported from editors, color is not set to [prop]currentColor. Usually monotone icons come with shapes that either use black color or system default color.

Sometimes icons also include white background, which needs to be removed. Parser cleans it up too.

System color

Usually, icons that use [prop]fill, do not have any colors:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
    <path d="M4 17h2.697L14 21.868V2.132L6.697 7H4c-1.103 0-2 .897-2 2v6c0 1.103.897 2 2 2z"/>
</svg>

Color in those icons is intended to be changed by changing [prop]fill property:

svg {
	fill: red;
}

Problem is, many icons use [prop]stroke instead of [prop]fill, so this approach does not apply to many icon sets, therefore it cannot be used.

Parser modifies those icons by setting [prop]fill to [prop]currentColor on elements that use system default [prop]fill:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
    <path d="M4 17h2.697L14 21.868V2.132L6.697 7H4c-1.103 0-2 .897-2 2v6c0 1.103.897 2 2 2z" fill="currentColor"/>
</svg>

Custom color

Usually when you export an icon from editor, it uses whatever color you were using when designing it, usually black:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
    <path d="M5 12H19" fill="none" stroke="black" stroke-width="2" stroke-linecap="round"/>
</svg>

Parser changes it to [prop]currentColor:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
    <path d="M5 12H19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>

Result

After changes, all shapes that use [prop]fill have [prop]fill set to [prop]currentColor, all shapes that use [prop]stroke have [prop]stroke set to [prop]currentColor, which means icon uses same color as text and can be styled as text:

svg {
	color: red;
}

Mixing palette and currentColor

Icons that mix [prop]currentColor and hardcoded palette are not allowed.

Such icons cannot be used in a stylesheet. In stylesheet monotone icons are used as masks, icons with palette are used as background. When the icon component detects [prop]currentColor in the icon, it assumes that the icon is monotone and uses it as a mask, displaying it incorrectly.

Also such icons assume that [prop]currentColor is either light or dark or cannot be a certain hue. It is just a bad design.

Code

Palette is parsed using the [func]parseColors() function from Iconify Tools.

validate

title: Validating SVG
functions:
  cleanupSVG: '/docs/libraries/tools/icon/cleanup.md'

Validating SVG

This article is part of SVG clean up article.

SVG can contain a lot of stuff that might be dangerous: scripts and external resources.

Style

Global [tag]style and inline [attr]style are converted to attributes.

Style complicates the process of analysing an icon structure, which is needed to later get rid of unused elements and parse the palette, so style should go. If style is too complex to parse or style overrides attribute, an exception is thrown.

Bad tags

During clean up, the icon is also checked for bad stuff.

Validation is very strict and opinionated.

Things that will cause validation to fail (function will throw an exception):

src: articles/script.svg
src: articles/image.svg

Removed tags

Clean up function has a list of all allowed SVG tags and their attributes.

If an unknown tag is encountered, this happens:

Attributes

Clean up function also checks each attribute on each element.

All attributes that do not affect icon rendering are removed.

If an event listener is found, the function throws an exception.

[attr]class attribute is allowed.

Inline [attr]style is converted to attributes (before parsing other attributes).

Text and fonts

All text tags are not allowed.

Why? Because different operating systems have different fonts, it will cause the icon to render differently.

This rule cannot be disabled.

src: articles/text.svg

Raster images

Sometimes raster images are used by icons for various purposes, usually masks or masked content.

They are not allowed. Why?

Clean up

Validation is done during clean up process.

It is done with the [func]cleanupSVG() function from Iconify Tools.

icon-v3

title: April 2025 Iconify icon components migration guide

Icon components migration guide

The following migration guide applies to:

New major versions of all components mentioned above was released in April 2025.

This was a breaking change, this migration guide should help you change your code.

Changes

Update introduces the following changes:

There are more changes for Vue and Svelte components, see below.

iconExists removal

Do not worry, function is not gone. It was renamed to [func]iconLoaded().

Reason for renaming function is really bad name. It was internal name in initial versions of component, used inside storage module. It checks if icon exists in storage, which makes sense within storage. However, when exported from component, function no longer storage specific, so it gave impression that it can be used to check if icon exists in Iconify API.

To avoid confusion, later function was renamed to [func]iconLoaded(), but old name [func]iconExists() was supported for backwards compatibility.

New major version is a good time to get rid of it.

Migration is as simple as it can get: change function name in your code.

Cache functions

Caching in storage is no longer available.

To migrate, simply remove usages of those functions.

See [/news/2025.md#components-storage](January 2025 news) for detailed explanation of why these functions were removed.

Vue changes

Vue component has been rewritten with Vue's Composition API. It does not change behavior, but now you can remove Options API from bundle if other components do not use it.

Other changes:

onLoad

Callback [prop]onLoad in Vue component has been replaced with [prop]load event.

Old code:

<template>
  <Icon icon="mdi:home" :onLoad="(icon) => console.log('Loaded', icon)" />
</template>

New code:

<template>
  <Icon icon="mdi:home" @load="(icon) => console.log('Loaded', icon)" />
</template>

Svelte

Svelte component has been rewritten using Svelte 5 runes.

If you are still using Svelte 4 or older version, new Svelte component will not work for you.

You need to use version 5 of component:

npm install --save-dev @iconify/svelte@4

or use a web component.

onLoad

Event [prop]on:load in Svelte component has been replaced with [prop]onload callback.

Old code:

<Icon icon="mdi:home" on:load={(event) => console.log('Loaded', event.detail.icon)} />

New code:

<Icon icon="mdi:home" onload={(icon) => console.log('Loaded', icon)} />

index

title: Iconify migration guides

Iconify migration guides

Migration guides for major releases.

2025

2024

index

title: "SVG animations level 2 spec: common issues and solutions"

Solving SVG animation spec issues

There are various ways to animate icons:

This article is about the last method: animating icons using SVG animations level 2 spec.

SMIL?

No, it is not the old deprecated SMIL animations.

It is a modern spec, though it is based on SMIL. Currenly it is supported by all modern browsers.

Sample

So what do SVG animations look like?

src: articles/animations/image-twotone.svg
demo: true
demoFirst: false
class: restart-animation

This example uses [tag]animate tag to change attributes of parent elements over time. It changes [prop]stroke-dashoffset to animate stroke, so it looks like icon is being drawn and [attr]fill-opacity to fade in filled elements.

No CSS, no JavaScript, no external dependencies.

See [tag]animate documentation on MDN and SVG animations level 2 spec for more examples, other related tags, attributes.

Timing

Unfortunately, SVG animations spec has one major downside: animation timing is very tricky to work with.

What exactly does that mean?

There are 2 ways to render SVGs:

Both have different problems with animation timing.

Inline SVG

When using inline [tag]svg, animations cannot start until document is ready.

It might seem like a small thing, but animations not rendering quickly enough can cause bad user experience.

This issue can be caused by small things, such as statistics script failing to load or ad code loading slowly. If at least one server that page is loading resources from is unreachable, it might break all animated SVGs on page. Async and defer attributes do not help. Issue can even be caused by script in an iframe.

Solution? {#solution-svg}

There is none.

If you website has a lot of external dependencies that might delay animation, do not use inline SVG for animated icons.

SVG as URL

When using icon as URL, you cannot control animation timing at all.

Animation always starts the first time icon is rendered. There is absolutely no way to control that.

Solution? {#solution-css}

The only solution is to generate unique URL for icon each time you need to restart animation.

The easiest way to achieve it is to add a basic HTML comment to icon content, like this:

.test-icon {
  --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath stroke-dasharray='20' stroke-dashoffset='20' d='M3 12h17.5'%3E%3Canimate fill='freeze' attributeName='stroke-dashoffset' dur='0.2s' values='20;0' /%3E%3C/path%3E%3Cpath stroke-dasharray='12' stroke-dashoffset='12' d='M21 12l-7 7M21 12l-7 -7'%3E%3Canimate fill='freeze' attributeName='stroke-dashoffset' begin='0.2s' dur='0.2s' values='12;0' /%3E%3C/path%3E%3C/g%3E%3C!-- 1234567890 --%3E%3C/svg%3E");
  width: 1em;
  height: 1em;
  background-color: currentcolor;
  mask-image: var(--svg);
  mask-repeat: no-repeat;
  mask-size: 100% 100%;
}

Notice [str]%3C!-- 1234567890 --%3E near end of URL. This is a simple comment with a number to break browser's cache.

Unfortunately, this solution requires JavaScript. It can be used as inline CSS, it cannot be used in CSS file.

Iconify web component

A simple solution to issues is to use Iconify icon web component web component.

Iconify icon web component renders animated icons as background or mask images and implements randomised URL workaround.

Additionally, it renders icons only when icon is visible. This means CPU is not wasted on animating invisible icons.

Conclusion

SVG animations spec is promising, but it is hard to use.

CSS animations are a better choice, but at the time of writing this, CSS animations are not fully supported yet by all major browsers (see update below). More specifically, only basic animations like [prop]stroke-dashoffset work, animating other attributes is not supported (see update below). This makes animating icons in CSS impossible beyond very basic animations.

Update

Update for CSS animations: April 2025.

In 2024 all major browsers added support for animating majority of SVG attributes in CSS.

The only exception is [prop]d attribute in path, which is actually the most important attribute. Safari 18.4 does not support animating or changing [prop]d in CSS, but it is supported in Safari TP, so hopefully support will land in Safari 18.5.