---
title: "Create an icon pack for TinyMCE"
description: "How to create a custom icon pack."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/creating-an-icon-pack/"
md_url: "https://www.tiny.cloud/docs/tinymce/latest/creating-an-icon-pack/index.md"
version: "latest"
last_updated: "2026-02-02T00:55:31Z"
tokens: 3149
---
# Create an icon pack for TinyMCE

## Overview

This guide provides comprehensive coverage of creating, building, and deploying custom icon packs, including solutions to common issues. It details two approaches:

- The manual approach, for adding a small number of custom icons
- Using the [Icon Pack Template tool](../using-the-icon-pack-template/) to easily generate the required output file from a folder of SVGs.

## How Icons Work in TinyMCE

A TinyMCE icon pack is a JavaScript construct containing strings of [SVGs](https://developer.mozilla.org/en-US/docs/Web/SVG). Icon packs are often kept in separate files, but can be inlined if needed. An icon pack can be used to add one or more custom icons or to replace some or all of the default TinyMCE icons.

An icon pack only **requires** the custom icons to be included; the default TinyMCE icons are used as a fallback for icons missing from the custom icon pack.

### Icon Pack Structure and Loading

> **Important:** **Understanding Icon Pack Loading:**
> 
> TinyMCE loads icon packs from the path `TINYMCE_BASE/icons/${iconPackName}/icons.js`, where:
> 
> - `TINYMCE_BASE` is the TinyMCE root directory (the directory containing `tinymce.min.js`).
> - `${iconPackName}` is the name of the icon pack.

## Registering an icon pack

Icon packs are registered with TinyMCE using the IconManager. Whether creating the icon pack manually or using the [Icon Pack Template tool](../using-the-icon-pack-template/), the JavaScript required to setup an icon pack looks like:

```javascript
tinymce.IconManager.add('custom-pack-name', {
  icons: {
    'bold': '<svg width="24" height="24">...</svg>',
    'italic': '<svg width="24" height="24">...</svg>',
    'custom-icon': '<svg width="24" height="24">...</svg>',
    // ... more icons
  }
});
```

## Creating an icon pack manually

When adding only a few icons, it may be easier to manually configure the new icon pack than to use the [Icon Pack Template tool](../using-the-icon-pack-template/). To do this:

1. Gather the SVG files for the new icons. Extract their content string, e.g. `<svg width="24" height="24">...</svg>`
2. Call `tinymce.IconManager.add()`
3. Specify the icon pack name as the first argument
4. The second argument is an object, with key `icons` and a nested object containing the new icons with their names and SVG strings as their keys and values.

The new icons can then be used by name within TinyMCE.

> **Important:** **Icon Override:** If custom icons have the same name as a default TinyMCE icon, they will override the default icon.
This JavaScript can be included as a separate icon file or inlined beside the application’s `tinymce.init()` call. Configure TinyMCE to load the icon pack and, if necessary, where from using the [`icons`](../editor-icons/#icons) and [`icons_url`](../editor-icons/#icons_url) options.

> **Note:** **Naming Icon Pack Files:** When loading icon packs from a separate file, it is safest to name the file `icons.js`. This ensures that, if placed in the default location, TinyMCE will recognize the file as an icon pack.

### Example: using a custom icon pack inline

```js
tinymce.IconManager.add('customIcons', { // icon pack name
  icons: { // list icons as name-SVG pairs
    'my-custom-icon': '<svg width="24" height="24">...</svg>',
  }
});

tinymce.init({
  selector: '#editor',
  icons: 'customIcons', // tell {productname} to load the custom icon pack
  toolbar: 'myCustomButton',
  setup: function(editor) {
    editor.ui.registry.addToolbarButton('myCustomButton', {
      icon: 'my-custom-icon' // use the custom icon for a custom toolbar button
    });
  }
});
```

## Using the Icon Pack Template tool

For large custom icon packs, use the [Icon Pack Template tool](../using-the-icon-pack-template/), which can take a folder of SVGs and generate the required output file. This approach is ideal when creating icon packs with many icons or when automating the build process.

For step-by-step instructions, see: [Using the Icon Pack Template tool](../using-the-icon-pack-template/).

## Deploying an Icon Pack file

An icon pack file can be served either:

- With TinyMCE
- Separate from TinyMCE

Use the [`icons`](../editor-icons/#icons) and [`icons_url`](../editor-icons/#icons_url) options to configure TinyMCE appropriately.

> **Note:** **Default Icon Pack Location:**
> 
> The `icons` option will only recognize icon files located at `TINYMCE_BASE/icons/${iconPackName}/icons.js`; where:
> 
> - `TINYMCE_BASE` is the TinyMCE root directory (the directory containing `tinymce.min.js`).

### Deploy the Icon Pack with TinyMCE

On initialization, TinyMCE will try to load any icon pack specified by the **icons** option. The icons in the icon pack will be merged with [TinyMCE’s default icons](../editor-icon-identifiers/) and icons in the icon pack will overwrite the default icons with the same identifier.

For custom icon packs:

```js
tinymce.init({
  selector: 'textarea',
  icons: 'my_icon_pack'  // TINYMCE_BASE/icons/my_icon_pack/icons.js
});
```

### Deploy the Icon Pack and TinyMCE Separately

On initialization, TinyMCE will try to load any icon pack specified by the **icons** option from the location specified by **icons_url**. The icons in the icon pack will be merged with [TinyMCE’s default icons](../editor-icon-identifiers/) and icons in the icon pack will overwrite the default icons with the same identifier.

> **Important:** **Understanding `icons_url` and `icons` Together:**
> 
> When using `icons_url`, you must also specify the `icons` option:
> 
> - `icons_url` - Tells TinyMCE **where** to find the icon pack file.
> - `icons` - Tells TinyMCE **which** icon pack to use from the loaded file.
> **Example:**
> 
> ```js
> tinymce.init({
> selector: 'textarea',
> icons_url: 'dist/icons/my_icon_pack/icons.js', // Where to find it
> icons: 'my_icon_pack',  // Which pack to use
> // ... other options
> });
> ```

## Usage

To use a TinyMCE icon pack from a separate location:

1. Ensure the icon pack is available at the specified URL.
2. Add the `icons_url` option to `tinymce.init`.
3. Specify the icon pack name using the `icons` setting.

For custom icon packs:

```js
tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  icons_url: 'dist/icons/my_icon_pack/icons.js', // Path to custom icon pack
  icons: 'my_icon_pack'  // Use custom icon pack
});
```

### Common Development Scenarios

#### Local Development with Custom Icon Pack

When developing locally with a custom icon pack:

```js
tinymce.init({
  selector: 'textarea',
  icons_url: 'dist/icons/my_icon_pack/icons.js', // Path to custom icon pack
  icons: 'my_icon_pack',  // Use custom icon pack
  toolbar: 'myButton',
  setup: (editor) => {
    editor.ui.registry.addButton('myButton', {
      icon: 'bold',    // Uses your custom bold icon
      onAction: (_) => {
        editor.insertContent('&nbsp;<strong>Custom icon clicked!</strong>&nbsp;');
      }
    });
  }
});
```

#### CDN Deployment

When deploying to a CDN or separate server:

```js
tinymce.init({
  selector: 'textarea',
  icons_url: 'https://cdn.example.com/icons/my_icon_pack/icons.js', // CDN URL
  icons: 'my_icon_pack',  // Use custom icon pack
  // ... other options
});
```

## Interactive Demo

See the custom icon pack in action with the interactive demo:

**Example**

```js
// Load custom icon pack inline (for live demo compatibility)
tinymce.IconManager.add('my-icon-pack', {
  icons: {
      'audio': '<svg width="24" height="24"><path d="M10.8 19q.9 0 1.5-.7t.7-1.5V13h3v-2h-4v3.9l-.6-.3-.6-.1q-1 0-1.7.7t-.6 1.6q0 .9.7 1.5t1.6.7ZM6 22q-.8 0-1.4-.6T4 20V4q0-.8.6-1.4T6 2h8l6 6v12q0 .8-.6 1.4T18 22H6Zm7-13h5l-5-5v5Z"/></svg>',
      'bold': '<svg width="24" height="24"><path fill-rule="evenodd" d="M3.6 2.3a1.4 1.4 0 0 0-1.4 1.3v16.8c0 .7.7 1.4 1.4 1.4h16.8a1.4 1.4 0 0 0 1.4-1.4V3.6a1.4 1.4 0 0 0-1.4-1.3H3.6Zm6 4a1.4 1.4 0 0 0-1.3 1.3v9.3c0 .7.6 1.4 1.3 1.4H12v-.8.8a2.5 2.5 0 0 0 .2 0 4.6 4.6 0 0 0 1.6-.5c.5-.2 1-.5 1.3-1 .4-.5.7-1.2.7-2 0-.9-.3-1.6-.7-2a3.2 3.2 0 0 0-.8-.9 2.8 2.8 0 0 0 .4-.5c.4-.5.5-1.1.5-1.9s-.1-1.4-.5-1.9a3 3 0 0 0-1.1-1 3.9 3.9 0 0 0-1.6-.3H9.6Zm.1 6.5H12a3.2 3.2 0 0 1 1.2.2l.7.6c.2.2.4.6.4 1.1s-.2 1-.4 1.2a1.8 1.8 0 0 1-.7.6 3.2 3.2 0 0 1-1.1.2H9.7v-4Zm2.3 4Zm0-5.6H9.7V7.8H12l1 .2.5.5c.1.2.3.5.3 1s-.2.8-.3 1a1.4 1.4 0 0 1-.6.5 2.3 2.3 0 0 1-.9.2Z" clip-rule="evenodd"/></svg>',
      'italic': '<svg width="24" height="24"><path fill-rule="evenodd" d="M3.6 2.3a1.4 1.4 0 0 0-1.4 1.3v16.8c0 .7.7 1.4 1.4 1.4h16.8a1.4 1.4 0 0 0 1.4-1.4V3.6a1.4 1.4 0 0 0-1.4-1.3H3.6ZM16 6.8h-1.5L11 17.1h1a.8.8 0 0 1 0 1.6H8a.8.8 0 0 1 0-1.6h1.5L13 6.8h-1a.8.8 0 0 1 0-1.5h4a.8.8 0 0 1 0 1.5Z" clip-rule="evenodd"/></svg>',
  }
});

// Default Icons Editor
tinymce.init({
selector: '#default-editor',
icons: 'material', // use material icon pack
plugins: 'lists link image code',
toolbar: 'undo redo | bold italic underline | bullist numlist | link image code',
height: 500,
// license_key: 'gpl'
});

// Custom Icons Editor
tinymce.init({
selector: '#custom-editor',
icons: 'my-icon-pack',
plugins: 'lists link image code',
toolbar: 'undo redo | myButton1 myButton2 myButton3 | bullist numlist | link image code',
height: 500,
setup: (editor) => {
  editor.ui.registry.addButton('myButton1', {
    icon: 'bold',    // the 'bold' icon created from 'bold.svg'
    onAction: (_) => {
      editor.insertContent('&nbsp;<strong>It\'s my custom bold icon button!</strong>&nbsp;');
    }
  });
  editor.ui.registry.addButton('myButton2', {
    icon: 'italic',    // the 'italic' icon created from 'italic.svg'
    onAction: (_) => {
      editor.insertContent('&nbsp;<strong>It\'s my custom italic icon button!</strong>&nbsp;');
    }
  });
  editor.ui.registry.addButton('myButton3', {
    icon: 'audio',    // the 'audio' icon created from 'audio.svg'
    onAction: (_) => {
      editor.insertContent('&nbsp;<strong>It\'s my custom audio icon button!</strong>&nbsp;');
    }
  });
}
});
```
