---
url: 'https://unocss.dev/extractors/arbitrary-variants.md'
---
# Arbitrary Variants Extractor
A more complex extractor to support arbitrary variants for utilities.
```html
```
Will be captured with `[&>*]:m-1` and `[&[open]]:p-2` as variants.
This extractor is included in [`@unocss/preset-mini`](/presets/mini) as the default extractor. Normally you don't need to install this package manually.
## Installation
::: code-group
```bash [pnpm]
pnpm add -D @unocss/extractor-arbitrary-variants
```
```bash [yarn]
yarn add -D @unocss/extractor-arbitrary-variants
```
```bash [npm]
npm install -D @unocss/extractor-arbitrary-variants
```
```bash [bun]
bun add -D @unocss/extractor-arbitrary-variants
```
:::
```ts [uno.config.ts]
import extractorArbitrary from '@unocss/extractor-arbitrary-variants'
import { defineConfig } from 'unocss'
export default defineConfig({
extractors: [
extractorArbitrary(),
],
})
```
---
---
url: 'https://unocss.dev/transformers/attributify-jsx.md'
description: Support valueless attributify in JSX/TSX (@unocss/transformer-attributify-jsx)
---
# Attributify JSX transformer
Support [valueless attributify](/presets/attributify#valueless-attributify) in JSX/TSX: `@unocss/transformer-attributify-jsx`.
## Presentation
```jsx
export function Component() {
return (
unocss
)
}
```
Will be transformed to:
```jsx
export function Component() {
return (
unocss
)
}
```
::: details Without this transformer, JSX treats valueless attributes as boolean attributes.
```jsx
export function Component() {
return (
unocss
)
}
```
:::
## Installation
::: code-group
```bash [pnpm]
pnpm add -D @unocss/transformer-attributify-jsx
```
```bash [yarn]
yarn add -D @unocss/transformer-attributify-jsx
```
```bash [npm]
npm install -D @unocss/transformer-attributify-jsx
```
```bash [bun]
bun add -D @unocss/transformer-attributify-jsx
```
:::
```ts{11} [uno.config.ts]
import { defineConfig, presetAttributify } from 'unocss'
import transformerAttributifyJsx from '@unocss/transformer-attributify-jsx'
export default defineConfig({
// ...
presets: [
// ...
presetAttributify(),
],
transformers: [
transformerAttributifyJsx(), // <--
],
})
```
::: tip
This preset is included in the `unocss` package, you can also import it from there:
```ts
import { transformerAttributifyJsx } from 'unocss'
```
:::
## Caveats
::: warning
The rules are almost the same as those of [Attributify preset](/presets/attributify), but there are several precautions.
:::
```html
```
Instead, you may want to use valued attributes instead:
```html
```
## Blocklist
This transformer will only transform attributes that are valid UnoCSS utilities.
You can also `blocklist` bypass some attributes from been transformed.
```js
transformerAttributifyJsx({
blocklist: [/text-[a-zA-Z]*/, 'text-5xl']
})
```
```jsx
unocss
```
Will be compiled to:
```html
unocss
```
---
---
url: 'https://unocss.dev/presets/attributify.md'
description: The UnoCSS preset that enables the attributify mode for other presets.
---
# Attributify preset
This enables the [attributify mode](#attributify-mode) for other presets.
[Source Code](https://github.com/unocss/unocss/tree/main/packages-presets/preset-attributify)
## Installation
::: code-group
```bash [pnpm]
pnpm add -D @unocss/preset-attributify
```
```bash [yarn]
yarn add -D @unocss/preset-attributify
```
```bash [npm]
npm install -D @unocss/preset-attributify
```
```bash [bun]
bun add -D @unocss/preset-attributify
```
:::
```ts [uno.config.ts]
import presetAttributify from '@unocss/preset-attributify'
export default defineConfig({
presets: [
presetAttributify({ /* preset options */ }),
// ...
],
})
```
::: tip
This preset is included in the `unocss` package, you can also import it from there:
```ts
import { presetAttributify } from 'unocss'
```
:::
## Attributify Mode
Imagine you have this button using Tailwind CSS's utilities. When the list gets longer, it becomes really hard to read and maintain.
```html
```
With attributify mode, you can separate utilities into attributes:
```html
```
For example, `text-sm text-white` could be grouped into `text="sm white"` without duplicating the same prefix.
## Prefix self-referencing
For utilities like `flex`, `grid`, `border`, that have the utilities same as the prefix, a special `~` value is provided.
For example:
```html
```
Can be written as:
```html
```
## Valueless attributify
In addition to Windi CSS's attributify mode, this preset also supports valueless attributes.
For example,
```html
```
now can be
```html
```
::: info
Note: If you are using JSX, `
```
### Extracting from Filesystem
In cases that you are using integrations that do not have access to the build tools pipeline (for example, the [PostCSS](/integrations/postcss) plugin), or you are integrating with backend frameworks such that the code does not go through the pipeline, you can manually specify the files to be extracted.
```ts [uno.config.ts]
export default defineConfig({
content: {
filesystem: [
'src/**/*.php',
'public/*.html',
],
},
})
```
The files matched will be read directly from the filesystem and watched for changes at dev mode.
### Extracting from Inline Text
Additionally, you can also extract utility usages from inline text that you might retrieve from elsewhere.
You may also pass an async function to return the content. But note that the function will only be called once at build time.
```ts [uno.config.ts]
export default defineConfig({
content: {
inline: [
// plain text
'
Some text
',
// async getter
async () => {
const response = await fetch('https://example.com')
return response.text()
},
],
},
})
```
## Limitations
Since UnoCSS works **at build time**, it means that only statically presented utilities will be generated and shipped to your app. Utilities that are used dynamically or fetched from external resources at runtime might **NOT** be detected or applied.
### Safelist
Sometimes you might want to use dynamic concatenations like:
```html
```
Due to the fact that UnoCSS works in build time using static extraction, at compile time it can't possibly know all the combinations of the utilities then. For that, you can configure the `safelist` option.
```ts [uno.config.ts]
safelist: 'p-1 p-2 p-3 p-4'.split(' ')
```
The corresponding CSS will always be generated:
```css
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-3 { padding: 0.75rem; }
.p-4 { padding: 1rem; }
```
Or more flexible:
```ts [uno.config.ts]
safelist: [
...Array.from({ length: 4 }, (_, i) => `p-${i + 1}`),
]
```
If you are seeking a true dynamic generation at runtime, you may want to check out the [@unocss/runtime](/integrations/runtime) package.
### Static List Combinations
Another way to work around the limitation of dynamically constructed utilities is that you can use an object that lists all the combinations **statically**. For example, if you want to have this:
```html
```
You can create an object that lists all the combinations (assuming you know any possible values of `color` you want to use)
```ts
// Since they are static, UnoCSS will be able to extract them at build time
const classes = {
red: 'text-red border-red',
green: 'text-green border-green',
blue: 'text-blue border-blue',
}
```
And then use it in your template:
```html
```
### Blocklist
Similar to `safelist`, you can also configure `blocklist` to exclude some utilities from being generated. This is useful for preventing extraction false positives.
But the blocklist is far more powerful than a simple exclusion list. In large-scale projects with many contributors, UnoCSS's flexibility — where the same visual result can be achieved with multiple utility syntaxes — becomes a liability. Different developers might write `border`, `border-1`, or `b` for the same CSS output, resulting in duplicate rules in the generated stylesheet, inconsistent code during reviews, and a growing CSS bundle. The blocklist lets you **enforce a single canonical syntax** across the entire codebase by blocking verbose or non-standard alternatives and pointing developers to the preferred form. Combined with `@unocss/eslint-plugin`, it acts as an automated style guide that restricts utilities to design system tokens, enforces the shortest aliases, and prevents arbitrary values — keeping CSS output minimal and the codebase consistent at scale.
#### Matcher Types
The `blocklist` accepts three matcher types:
**String** — exact match:
```ts [uno.config.ts]
blocklist: [
'p-1', // blocks p-1 exactly
'tab', // blocks tab exactly
]
```
**RegExp** — pattern match (uses `.test()`):
```ts [uno.config.ts]
blocklist: [
/^p-[2-4]$/, // blocks p-2, p-3, p-4
/^border$/, // blocks "border" but not "border-2"
]
```
**Function** — custom logic, returns truthy to block:
```ts [uno.config.ts]
blocklist: [
s => s.endsWith('px'), // block all px-suffixed classes
s => s.split('-').length > 4, // block deeply nested utilities
]
```
#### Messages
Each matcher can optionally be wrapped in a tuple containing a `message` that explains why the utility is blocked. The message can be a static string or a callback that receives the matched selector:
```ts [uno.config.ts]
blocklist: [
// static message
[/^border$/, { message: 'use shorter "b"' }],
// dynamic message — receives the blocked selector
[/^border(?:-[btrlxy])?$/, {
// e.g. "border-y" → 'use shorter "b-y"'
message: v => `use shorter "${v.replace(/^border/, 'b')}"`
}],
]
```
When used with `@unocss/eslint-plugin`, the message appears in lint output:
```shell
"border" is in blocklist: use shorter "b"
```
Without the ESLint plugin, blocked utilities are silently excluded from CSS generation with no feedback to the developer.
**It is recommended to use `@unocss/eslint-plugin` alongside blocklist rules** to surface actionable messages during development.
#### Variant Awareness
The blocklist checks selectors **both before and after variant stripping**.
A rule blocking `p-1` will also block `hover:p-1`, `md:p-1`, `dark:p-1`, etc.
You don't need to account for variant prefixes in your blocklist patterns.
#### Merging Behavior
Blocklist arrays from all presets and the user config are **merged** — they accumulate and never override each other.
A utility blocked by any preset or the user config will remain blocked.
#### Type Reference
```ts
type BlocklistValue = string | RegExp | ((selector: string) => boolean | null | undefined)
type BlocklistRule = BlocklistValue | [BlocklistValue, BlocklistMeta]
interface BlocklistMeta {
/**
* Custom message to show why this selector is blocked.
*/
message?: string | ((selector: string) => string)
}
```
### Blocklist Patterns
Below are common patterns for using the blocklist effectively.
#### Enforcing Shorter Aliases
When UnoCSS supports multiple syntaxes for the same CSS output, you can block the verbose form and suggest the shorter one:
```ts [uno.config.ts]
blocklist: [
// "border" → "b", "border-t" → "b-t"
[/^border(?:-[btrlxy])?$/, {
message: v => `use shorter "${v.replace(/^border/, 'b')}"`
}],
// "opacity-50" → "op-50"
// "backdrop-opacity-50" → "backdrop-op-50"
[/^(?:backdrop-)?opacity-(.+)$/, {
message: v => `use shorter "${v.replace(/opacity-/, 'op-')}"`
}],
// "whitespace-nowrap" → "ws-nowrap"
[/^whitespace-.+$/, {
message: v => `use shorter "${v.replace(/^whitespace-/, 'ws-')}"`
}],
// simple static aliases work well for one-to-one replacements
[/^flex-grow$/, { message: 'use shorter "grow"' }],
[/^flex-shrink$/, { message: 'use shorter "shrink"' }],
[/^inline-block$/, { message: 'use shorter "i-block"' }], // you can point to your custom shortcuts as well
]
```
#### Restricting to Design System Tokens
You can dynamically build blocklist patterns from your design system config to ensure only valid tokens are used.
Use a negative lookahead to permit valid values while blocking everything else:
```ts [uno.config.ts]
import { theme } from './my-design-system'
// Helper to join object keys into a regex alternation
const keys = (obj: Record) => Object.keys(obj).join('|')
blocklist: [
// Only allow font families defined in the design system
[new RegExp(`^font-(?!(?:${keys(theme.fontFamily)}|\\$)$).+$`), {
message: `use design system font families: ${Object.keys(theme.fontFamily).join(', ')}`
}],
// Only allow shadow values from the design system
[new RegExp(`^shadow-(?!(?:${keys(theme.boxShadow)}|\\$)).+$`), {
message: `only design system shadow values are allowed.`
}],
]
```
::: tip
The `\\$` in the negative lookahead allows CSS variable references (e.g., `font-$myVar`) to pass through, since those are resolved at runtime and can't be statically validated.
:::
#### Converting Raw Units to Scale Values
If your project uses the UnoCSS default spacing scale (where 1 unit = 0.25rem = 4px), you can block raw `px` and `rem` values and suggest the scale equivalent:
```ts [uno.config.ts]
blocklist: [
// "mt-16px" → "mt-4"
// "p-[8px]" → "p-2"
// "w-2rem" → "w-8"
[/^.+-\[?[\d.]+(?:px|rem)\]?$/, {
message: (s) => {
// since message() only receives the matched selector string, not the regex
// we have to match it again to extract capture groups from the blocklist matcher
const m = s.match(/\[?(?[\d.]+)(?px|rem)\]?$/)!
const { v, u } = m.groups!
const scale = u === 'rem' ? +v * 4 : +v / 4
return `use spacing scale value: ${s.slice(0, -m[0].length)}${scale}`
}
}],
]
```
#### Removing Unnecessary Brackets
UnoCSS arbitrary value brackets `[...]` are often unnecessary when the value is already valid without them:
```ts [uno.config.ts]
blocklist: [
// "w-[50%]" → "w-50%"
[/^(w|h|min-[wh]|max-[wh]|top|right|bottom|left)-\[\d+%\]$/, {
message: (v) => {
const value = v.match(/\[(\d+%)\]/)?.[1] || ''
return `use shorter ${v.replace(/-\[\d+%\]/, `-${value}`)}`
}
}],
// "outline-[#ff0000]" → "outline-#ff0000"
[/^[a-z-]+-\[#[0-9a-fA-F]{3,6}\]$/, {
message: v => `use shorter ${v.replace(/\[#/, '#').replace(/\]/, '')}`
}],
]
```
#### Enforcing Conventions
Block patterns that violate project-specific architectural decisions:
```ts [uno.config.ts]
blocklist: [
// Prevent redundant breakpoint — if "sm" equals 0, it's always active
// in mobile-first responsive design and should not be specified
[/^sm:/, {
message: v => `sm: breakpoint is redundant, use "${v.replace(/^sm:/, '')}"`
}],
// Force separate utility classes instead of slash opacity notation.
// Separate utilities have a higher chance of reuse than slashed combinations,
// which helps reduce the resulting CSS bundle size
// "bg-red-500/50" → "bg-red-500 bg-op-50"
[/^(c|bg)-.+\/\d+$/, {
message: 'use separate opacity class instead of slash notation (e.g., "bg-red bg-op-50").'
}],
// Decompose shorthands into reusable individual properties.
// Same principle — separate utilities reduce CSS bundle size
// "size-4" → "w-4 h-4"
[/^size-(.+)$/, {
message: (v) => {
const size = v.match(/^size-(.+)$/)?.[1]
return `use "w-${size} h-${size}" for independent control`
}
}],
]
```
---
---
url: 'https://unocss.dev/config/extractors.md'
---
# Extractors
Extractors are used to extract the usage of utilities from your source code.
```ts [uno.config.ts]
import { defineConfig } from 'unocss'
export default defineConfig({
extractors: [
// your extractors
],
})
```
By default [extractorSplit](https://github.com/unocss/unocss/blob/main/packages-engine/core/src/extractors/split.ts) will always be applied, which splits the source code into tokens and directly feed to the engine.
To override the default extractors, you can use `extractorDefault` option.
```ts [uno.config.ts]
import { defineConfig } from 'unocss'
export default defineConfig({
extractors: [
// your extractors
],
// disable the default extractor
extractorDefault: false,
// override the default extractor with your own
extractorDefault: myExtractor,
})
```
For example, please check the implementation of [pug extractor](https://github.com/unocss/unocss/blob/main/packages-presets/extractor-pug/src/index.ts) or the [attributify extractor](https://github.com/unocss/unocss/blob/main/packages-presets/preset-attributify/src/extractor.ts).
---
---
url: 'https://unocss.dev/guide.md'
description: Getting started with UnoCSS
---
# What is UnoCSS?
UnoCSS is the instant atomic CSS engine, that is designed to be flexible and extensible. The core is un-opinionated and all the CSS utilities are provided via presets.
For example, you could define your custom CSS utilities, by providing rules in your local [config file](/guide/config-file).
```ts [uno.config.ts]
import { defineConfig } from 'unocss'
export default defineConfig({
rules: [
['m-1', { margin: '1px' }],
],
})
```
This will add a new CSS utility `m-1` to your project. Since UnoCSS is on-demand, it won't do anything until you use it in your codebase. So say we have a component like this:
```html
Hello
```
`m-1` will be detected and the following CSS will be generated:
```css
.m-1 { margin: 1px; }
```
To make it more flexible, you can make your rule dynamic by changing the first argument on the rule (we call it matcher) to a `RegExp`, and the body to a function, for example:
```diff [uno.config.ts]
export default defineConfig({
rules: [
- ['m-1', { margin: '1px' }],
+ [/^m-([\.\d]+)$/, ([_, num]) => ({ margin: `${num}px` })],
],
})
```
By doing this, now you can have arbitrary margin utilities, like `m-1`, `m-100` or `m-52.43`. And again, UnoCSS only generates them whenever you use them.
```html
Hello
World
```
```css
.m-1 { margin: 1px; }
.m-7.5 { margin: 7.5px; }
```
## Presets
Once you made a few rules, you can extract them into a preset, and share it with others. For example, you can create a preset for your company's design system, and share it with your team.
```ts [my-preset.ts]
import { Preset } from 'unocss'
export const myPreset: Preset = {
name: 'my-preset',
rules: [
[/^m-([.\d]+)$/, ([_, num]) => ({ margin: `${num}px` })],
[/^p-([.\d]+)$/, ([_, num]) => ({ padding: `${num}px` })],
],
variants: [/* ... */],
shortcuts: [/* ... */],
// ...
}
```
```ts [uno.config.ts]
import { defineConfig } from 'unocss'
import { myPreset } from './my-preset'
export default defineConfig({
presets: [
myPreset, // your own preset
],
})
```
So similarly, we provided a few [official presets](/presets/) for you to start using right away, and you can also find many interesting [community presets](/presets/community).
## Play
You can try UnoCSS in your browser, in the Playground. Or look up utilities from the default presets in the Interactive Docs.
## Integrations
UnoCSS comes with integrations for various frameworks / tools:
## Examples
Source code for all the examples can be found in the [/examples](https://github.com/unocss/unocss/tree/main/examples) directory.
---
---
url: 'https://unocss.dev/presets/icons.md'
description: Use any icon with Pure CSS for UnoCSS (@unocss/preset-icons).
---
# Icons preset
Use any icon with Pure CSS for UnoCSS.
[Source Code](https://github.com/unocss/unocss/tree/main/packages-presets/preset-icons)
::: tip
Recommended reading: [Icons in Pure CSS](https://antfu.me/posts/icons-in-pure-css)
:::
Follow the following conventions to use the icons
* `-`
* `:`
For example:
```html
```
Check [all available icons](https://icones.js.org/).
## Install
::: code-group
```bash [pnpm]
pnpm add -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
```
```bash [yarn]
yarn add -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
```
```bash [npm]
npm install -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
```
```bash [bun]
bun add -D @unocss/preset-icons @iconify-json/[the-collection-you-want]
```
:::
We use [Iconify](https://iconify.design) as our data source of icons. You need to install the corresponding icon-set in `devDependencies` by following the `@iconify-json/*` pattern. For example, `@iconify-json/mdi` for [Material Design Icons](https://materialdesignicons.com/), `@iconify-json/tabler` for [Tabler](https://tabler-icons.io/). You can refer to [Icônes](https://icones.js.org/) or [Iconify](https://icon-sets.iconify.design/) for all the collections available.
```ts [uno.config.ts]
import presetIcons from '@unocss/preset-icons'
import { defineConfig } from 'unocss'
export default defineConfig({
presets: [
presetIcons({ /* options */ }),
// ...other presets
],
})
```
::: tip
This preset is included in the `unocss` package, you can also import it from there:
```ts
import { presetIcons } from 'unocss'
```
:::
::: info
You can also use this preset alone as a complement to your existing UI frameworks to have pure CSS icons!
:::
If you prefer to install all the icon sets available on Iconify at once (~130MB):
::: code-group
```bash [pnpm]
pnpm add -D @iconify/json
```
```bash [yarn]
yarn add -D @iconify/json
```
```bash [npm]
npm install -D @iconify/json
```
```bash [bun]
bun add -D @iconify/json
```
:::
### Extra Properties
You can provide the extra CSS properties to control the default behavior of the icons. The following is an example of making icons inlined by default:
```ts
presetIcons({
extraProperties: {
'display': 'inline-block',
'vertical-align': 'middle',
// ...
},
})
```
## Modes Overriding
By default, this preset will choose the rendering modes automatically for each icon based on the icons' characteristics. You can read more in this [blog post](https://antfu.me/posts/icons-in-pure-css). In some cases, you may want to explicitly set the rendering modes for each icon.
* `?bg` for `background-img` - renders the icon as a background image
* `?mask` for `mask` - renders the icon as a mask image
For example, `vscode-icons:file-type-light-pnpm`, an icon with colors (the `svg` doesn't contain `currentColor`) that will be rendered as a background image. Use `vscode-icons:file-type-light-pnpm?mask` to render it as a mask image and bypass it's colors.
```html
```
## Configuring collections and icons resolvers
You can provide collections via `@iconify-json/[the-collection-you-want]`, `@iconify/json` or using your custom ones using `collections` option on your `UnoCSS` configuration.
### Browser
To load `iconify` collections you should use `@iconify-json/[the-collection-you-want]` and not `@iconify/json` since the `json` file is huge.
#### Bundler
When using bundlers, you can provide the collections using `dynamic imports` so they will be bundler as async chunk and loaded on demand.
```ts
import presetIcons from '@unocss/preset-icons/browser'
export default defineConfig({
presets: [
presetIcons({
collections: {
carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default),
mdi: () => import('@iconify-json/mdi/icons.json').then(i => i.default),
logos: () => import('@iconify-json/logos/icons.json').then(i => i.default),
}
})
]
})
```
#### CDN
Or if you prefer to fetch them from CDN, you can specify the `cdn` option since `v0.32.10`. We recommend [esm.sh](https://esm.sh/) as the CDN provider.
```ts
presetIcons({
cdn: 'https://esm.sh/'
})
```
#### Customization
You can also provide your own custom collections using [CustomIconLoader](https://github.com/iconify/iconify/blob/master/packages/utils/src/loader/types.ts#L17) or [InlineCollection](https://github.com/iconify/iconify/blob/master/packages/utils/src/loader/types.ts#L86), for example using `InlineCollection`:
```ts
presetIcons({
collections: {
custom: {
circle: '',
/* ... */
},
carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default as any),
/* ... */
}
})
```
And then, you can use it on your html: ``
### Node.js
In `Node.js` the preset will search for the installed iconify dataset automatically, so you don't need to register the `iconify` collections.
You can also provide your own custom collections using also [CustomIconLoader](https://github.com/iconify/iconify/blob/master/packages/utils/src/loader/types.ts#L24) or [InlineCollection](https://github.com/iconify/iconify/blob/master/packages/utils/src/loader/types.ts#L100).
#### FileSystemIconLoader
Additionally, you can also use [FileSystemIconLoader](https://github.com/iconify/iconify/blob/master/packages/utils/src/loader/node-loaders.ts#L9) to load your custom icons from your file system. You will need to install `@iconify/utils` package as `dev dependency`.
```ts [unocss.config.ts]
import fs from 'node:fs/promises'
// loader helpers
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
import { defineConfig, presetIcons } from 'unocss'
export default defineConfig({
presets: [
presetIcons({
collections: {
// key as the collection name
'my-icons': {
account: '',
// load your custom icon lazily
settings: () => fs.readFile('./path/to/my-icon.svg', 'utf-8'),
/* ... */
},
'my-other-icons': async (iconName) => {
// your custom loader here. Do whatever you want.
// for example, fetch from a remote server:
return await fetch(`https://example.com/icons/${iconName}.svg`).then(res => res.text())
},
// a helper to load icons from the file system
// files under `./assets/icons` with `.svg` extension will be loaded as it's file name
// you can also provide a transform callback to change each icon (optional)
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/#fff/, 'currentColor')
)
}
})
]
})
```
#### ExternalPackageIconLoader
From `@iconify/utils v2.1.20` you can use other packages to load icons from others authors using the new [createExternalPackageIconLoader](https://github.com/iconify/iconify/blob/main/packages/utils/src/loader/external-pkg.ts#L13) helper.
::: warning WARNING
External packages must include `icons.json` file with the `icons` data in `IconifyJSON` format, which can be exported with Iconify Tools. Check [Exporting icon set as JSON package](https://iconify.design/docs/libraries/tools/export/json-package.html) for more details.
:::
For example, you can use `an-awesome-collection` or `@my-awesome-collections/some-collection` to load your custom or third party icons:
```ts [unocss.config.ts]
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
import { defineConfig, presetIcons } from 'unocss'
export default defineConfig({
presets: [
presetIcons({
collections: createExternalPackageIconLoader('an-awesome-collection')
})
]
})
```
You can also combine it with other custom icon loaders, for example:
```ts [unocss.config.ts]
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
import { defineConfig, presetIcons } from 'unocss'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
export default defineConfig({
presets: [
presetIcons({
collections: {
...createExternalPackageIconLoader('other-awesome-collection'),
...createExternalPackageIconLoader('@my-awesome-collections/some-collection'),
...createExternalPackageIconLoader('@my-awesome-collections/some-other-collection'),
'my-yet-other-icons': FileSystemIconLoader(
'./assets/icons',
svg => svg.replace(/^