# Iconify icon sets, cleaned JSON for two hundred icon libraries

> The icon-sets repository is a data package rather than a component library. It holds two hundred or more open source icon sets converted to a single JSON format, with every icon stripped of scripts, event listeners, fonts, raster images and external references, monotone colours rewritten to currentColor, and the whole collection refreshed several times a week. The interesting engineering is in the format and in the cleaning rules, not in the rendering.

**iconify/icon-sets** — 200+ open source icon sets. Icons are validated, cleaned up, optimised, ready to render as SVG. Updated automatically several times a week.

- Repository: https://github.com/iconify/icon-sets
- Website: https://icon-sets.iconify.design/
- Stars: 1,069 · Forks: 96
- Language: TypeScript
- License: not declared
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/iconify-icon-sets

## A data package, and a description that undersells it

The repository describes itself as a big collection of open source vector icons, all validated, cleaned up and converted to the same easy to use format, and the project description gives the scale as 200+ open source icon sets that are validated, cleaned up, optimised and ready to render as SVG, updated automatically several times a week.

The important thing about the repository is what it is not. It is not a component library, it does not ship a Vue or React component, and it does not render anything. It is data, distributed as the npm package @iconify/json, and the version in the package manifest is 2.2.543, which is the clearest hint that the package is republished whenever any upstream set changes.

That distinction decides who should use it. A front-end team that wants an icon in a component reaches for a binding package, which is a different repository. A team that wants the icon data itself, to build its own component, to generate a font, to render server-side, or to slice a set for a design system, wants this one.

The format is called IconifyJSON, and a TypeScript definition of it lives in the @iconify/types package. The readme also points at Iconify Utils as the library for working with the data, and makes a point about it that matters for adoption: the utils package works in any JavaScript environment, Node.js, Deno, browsers and isolated JavaScript environments.

## The cleaning rules are the real product

Every icon in the collection has been processed with Iconify Tools, and the rules are strict enough to be worth quoting because they are what makes this collection safe to embed in a page.

Icons do not contain scripts, event listeners, fonts, raster images, external resources and unknown elements. That is a security property, not a formatting preference. An icon set that embedded a script tag or an event handler would be a script injection vector in every application that displayed it, and a collection that mixes hundreds of upstream sets needs one rule applied uniformly to be usable at all.

Colours for monotone icons have been replaced with currentColor, so the icon takes the colour of the text around it, which means an application can theme an icon with a CSS colour without editing the icon data. Icon content has also been optimised to reduce its size, which matters when a page renders forty icons.

There is a caveat that sits next to all of this, and the readme states it in one line: even though all icon sets are open source, some icon sets require attribution. The collections.md file in the repository root is the list of icon sets and their licences, and it is the document to check before shipping a particular set.

That combination, uniform sanitisation with per-set attribution obligations, is the shape of the problem. The rules are applied centrally so that no application has to audit two hundred upstreams, and the obligations are documented centrally so that no application has to discover them later.

## Why JSON and not SVG

The readme devotes a section to the format decision, and the reasons are the interesting part of the design.

Easy to store images in bulk is the first reason. Storing icons in bulk inside one package is a different problem from shipping a file per icon, and the difference shows up in install time, in repository size and in tooling.

The second is that the format contains only the content of the icon without the svg element, which makes it easy to manipulate the content without doing complex parsing, and it makes it easier to create components, such as a React icon component, allowing the framework's native SVG element to be used. That is a subtle but real advantage. A component that emits its own svg element can apply the framework's attributes, events and ref behaviour, and the icon data is just the inner content. If the data were SVG documents, every framework binding would have to parse them and pull the body out again.

The third is that the data can contain additional content: aliases for icons, icon set information, and categories, tags and themes. The last of those is what makes a large collection searchable, and none of it fits inside an SVG document.

The section on why not XML has one reason: JSON is much easier to parse without additional tools, and all languages support it. For a data format that has to be read by a PHP application, a Python script, a Go tool and a browser, that is the deciding argument.

## The format's vocabulary and the alias mechanism

The JSON format is small, and the readme documents every field.

The icons object lists all the icons, keyed by name. Each icon has a body, which is the icon content, and then the optional geometry and transformation properties. left and top are the coordinates of the viewBox, defaulting to 0. width and height are the dimensions of the viewBox, defaulting to 16. rotate is the rotation, with 0 meaning no rotation, then 90, 180 and 270 degrees. hFlip and vFlip are the horizontal and vertical flips, booleans defaulting to false.

Then there is hidden, and its description is the one that explains why the format keeps things it no longer uses. If it is set to true, the icon is hidden, which means it was removed from the collection for some reason, but it is kept in the JSON file to prevent applications that rely on the old icon from breaking. A missing key and a hidden key are different facts, and a data format for icons is exactly the kind of thing where a consumer's cached lookup would break if a key simply disappeared.

The aliases object is the other half. An alias has a parent that points to the parent icon and no body of its own, and the transformation properties, rotate, hFlip and vFlip, are merged with the parent's properties, while any other property overwrites the parent's. So an alias is a named variant of an icon rather than a copy of it, which is how a set that contains the same glyph at four rotations or in two weights avoids storing it four times.

The format also reduces duplication in a second way. When multiple icons have the same value, it is moved to the root object, so a set whose icons are mostly 24 by 24 can declare the size once instead of on every icon.

## Getting the data into a Node or PHP project

The readme gives instructions for two ecosystems, and both are deliberately thin.

For a Node.js project, one command adds the collection:

```bash
npm install --save @iconify/json
```

The icons then live in node_modules/@iconify/json, and resolving the file for a given set is a single call:

```js
import { locate } from '@iconify/json';

// returns location of mdi-light.json
const mdiLightFilename = locate('mdi-light');
```

For PHP, the instruction is to install and initialise a Composer project, add a requirement to composer.json and run composer install:

```json
"require": {
    "php": ">=5.6",
    "iconify/json": "*"
}
```

The icons then appear in vendor/iconify/json/, and the PHP equivalent of locate is a static call on the Finder class:

```php
// Returns location of mdi-light.json
$mdiLightLocation = \Iconify\IconsJSON\Finder::locate('mdi-light');
```

If you do not use Composer, the readme says to clone the GitHub repository and add the necessary autoload code.

What is notable is the scope of the dependency. A project that only needs one icon set still installs the lot, and the whole collection arrives as a package rather than as a fetch at runtime, which means the size question is decided at install time rather than at page load.

## From JSON to individual SVG files

The readme's last technical section covers the case where you want files rather than data, and it is the one place where the tooling matters.

Iconify Utils is enough for a simple export, and Iconify Tools offers more options. The example is written in TypeScript and shows the whole pipeline: locate the JSON file for a set, read it, parse it with parseIconSet, and render each icon with iconToSVG using the shared defaults, with the height set to auto.

```ts
import { promises as fs } from 'fs';
import { locate } from '@iconify/json';
import { parseIconSet } from '@iconify/utils/lib/icon-set/parse';
import { iconToSVG } from '@iconify/utils/lib/svg/build';
import { defaults } from '@iconify/utils/lib/customisations';
```

The rest of the example assembles the SVG element itself, with the xmlns and xmlns:xlink attributes plus the attributes produced by the renderer, and the comment in the code explains why the attribute values are not escaped: the attribute names and values cannot contain anything that needs escaping. That is a small thing to be careful about, and it is the kind of comment that only appears in code that has been audited.

Each icon goes through a callback, an invalid icon is logged and skipped, and the rendered SVGs are collected into an object and written to an output directory. The result is a directory of individual SVG files generated from the cleaned JSON, which is what a design system or a documentation site usually wants.

The alternative to writing that script is to use the components that ship with the Iconify project, which the readme points to for more usage detail, including exporting the icons individually as SVG files.

## Where the collection is the wrong tool

The first limit is the packaging. Installing @iconify/json gives you every icon set in the collection, which is a large package for a project that needs three icons, and there is no documented way to install a single set from it. The trade is deliberate, since the package is a data bundle that is republished on every upstream change, and the alternative of fetching icons at runtime moves the problem to the network.

The second is the churn. The repository is updated automatically several times a week, and the package version 2.2.543 says the same thing numerically. A project that pins the version gets a stable snapshot; a project that tracks the latest gets new icons and, in principle, changes to existing ones, since the cleaning and optimisation rules are applied again on every pass. Pinning is the sane choice for an application and the wrong choice for a project that wants to mirror upstream exactly.

The third is attribution. The sets are all open source, but some require attribution, and the readme points at collections.md for the list. That is a per-set obligation that a design system has to track, and it does not go away by using the collection.

The fourth is what the collection is not. There is no component, no framework binding and no renderer here, and a team whose goal is to have an icon component with tree shaking and no runtime cost should be looking at the binding packages rather than at this data.

The fifth is the licence labelling, which is inconsistent and worth resolving before use. The package manifest says MIT, and the repository itself carries no licence classification, and the collections have their own separate terms. For a package that redistributes two hundred third-party icon sets, the per-set licences are the ones that matter, and the top-level statement is not the whole of it.

## Conclusion

The Iconify icon sets fit a project that wants hundreds of icon libraries in one consistent, sanitised format without running each upstream's build, and the npm and Composer packages make it a two-line install for Node and PHP projects alike. It does not fit a project that wants a Vue or React component with icons already in it, because this is data and the binding packages are elsewhere, and it does not fit a team that cannot accept a collection that changes several times a week without a version pin. Before adopting it, read collections.md, because the sets are all open source but some require attribution, and check that the licence of the set you plan to ship is one you can live with, since the repository's own licence labelling is inconsistent, with MIT in the package manifest and no classification on the repository. The package version is 2.2.543 and the last push was on 2026-10-15.

## FAQ

### How do I install the Iconify JSON icon sets?

For a Node.js project, `npm install --save @iconify/json`, and the icons appear under node_modules/@iconify/json. For PHP, add iconify/json to the require block of composer.json with a PHP version of at least 5.6 and run composer install, after which the icons are in vendor/iconify/json.

### How do I find the JSON file for one icon set?

With the locate helper, which returns the path of the set's JSON file, for example locate('mdi-light') in JavaScript and \Iconify\IconsJSON\Finder::locate('mdi-light') in PHP. The location function is exported from the @iconify/json package.

### Are the icons in the collection sanitised?

Yes. Every icon has been processed with Iconify Tools, and the readme states that icons do not contain scripts, event listeners, fonts, raster images, external resources or unknown elements, that monotone icon colours are replaced with currentColor, and that the content is optimised for size.

### Do all the icon sets have the same licence?

No. All of the sets are open source, but some require attribution. The collections.md file in the repository lists the icon sets and their licences, and it is the file to check before shipping a particular set.

### What is the difference between an icon and an alias in IconifyJSON?

An alias has a parent property pointing at the parent icon and no body of its own. Its transformation properties, rotate, hFlip and vFlip, are merged with the parent's, while any other property overwrites the parent's value.

## Sources

- [iconify/icon-sets on GitHub](https://github.com/iconify/icon-sets)
- [Issues](https://github.com/iconify/icon-sets/issues)
- [Project website](https://icon-sets.iconify.design/)
- [README](https://github.com/iconify/icon-sets/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/iconify-icon-sets
