---
title: "Bundling TinyMCE plugins using module loading"
description: "Information on bundling TinyMCE plugins using module loading"
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/bundling-plugins/"
md_url: "https://www.tiny.cloud/docs/tinymce/latest/bundling-plugins/index.md"
version: "latest"
last_updated: "2026-04-10T10:26:04Z"
tokens: 4152
---
# Bundling TinyMCE plugins using module loading

## Overview

TinyMCE plugins can be bundled using a module bundler such as Webpack, Rollup, or Vite. This guide covers how to include both community and premium plugins in your application bundle.

TinyMCE includes both community and premium plugins:

- **Community plugins**: Available with all TinyMCE installations
- **Premium plugins**: Available with paid TinyMCE subscriptions via the `tinymce-premium` package

## File structure

This section shows the files required for each TinyMCE plugin. The file paths shown are relative to the root TinyMCE package directory, where `tinymce.min.js` is stored. For example:

```
./
├── icons/
├── langs/
├── license.txt
├── models/
├── plugins/
├── readme.txt
├── skins/
├── themes/
├── tinymce.d.ts
├── tinymce.js
├── tinymce.min.js
└── version.txt
```

## Required base folder

The below base folder is required for each plugin when bundling TinyMCE.

```js
./plugins/<plugincode>
```

## Bundling syntax examples

The following examples show the syntax for including plugins in a bundle. The examples use a placeholder `<plugincode>` to represent any plugin name:

**Module Syntax:** ES6+ · **Source:** npm (community plugins)

**Example:**

```js
import 'tinymce/plugins/<plugincode>';
```
**Module Syntax:** ES6+ · **Source:** npm (premium plugins)

**Example:**

```js
import 'tinymce-premium/plugins/<plugincode>';
```
**Module Syntax:** ES6+ · **Source:** `.zip` (community plugins)

**Example:**

```js
import '<path_to_tinymce_zip>/plugins/<plugincode>';
```
**Module Syntax:** ES6+ · **Source:** `.zip` (premium plugins)

**Example:**

```js
import '<path_to_tinymce_premium_zip>/plugins/<plugincode>';
```
**Module Syntax:** Common JS · **Source:** npm (community plugins)

**Example:**

```js
require('tinymce/plugins/<plugincode>');
```
**Module Syntax:** Common JS · **Source:** npm (premium plugins)

**Example:**

```js
require('tinymce-premium/plugins/<plugincode>');
```
**Module Syntax:** Common JS · **Source:** `.zip` (community plugins)

**Example:**

```js
require('<path_to_tinymce_zip>/plugins/<plugincode>');
```
**Module Syntax:** Common JS · **Source:** `.zip` (premium plugins)

**Example:**

```js
require('<path_to_tinymce_premium_zip>/plugins/<plugincode>');
```

## Using premium plugins

After installing the `tinymce-premium` package, configure the plugins in the editor using one of two fully supported approaches. Both options are production-ready and will continue to be supported in future releases:

- **[Bundling](#bundling-recommended)** — includes plugin code directly in the application bundle using a module bundler
- **[Loading with `external_plugins`](#using-external-plugins)** — loads plugins at runtime from a specified URL, enabling lazy-loading and CDN hosting

The right choice depends on the application architecture and deployment requirements.

> **Important:** **License Key Manager Requirement:**
> 
> When using premium plugins with a commercial license, you must include the `licensekeymanager` plugin. The editor will not function properly without it. For more information, see: [License Key](../license-key/).
> 
> **[When bundling](#bundling-recommended):**
> 
> ```js
> import 'tinymce-premium/plugins/licensekeymanager';
> ```
> **[When using `external_plugins`](#using-external-plugins):**
> 
> ```js
> external_plugins: {
> 'licensekeymanager': '<path_to_premium_plugins>/licensekeymanager/plugin.min.js'
> }
> ```

### Bundling

Bundling includes the plugin code directly in the application bundle. This approach works well for applications that already use a module bundler such as Webpack, Vite, or Rollup.

1. Import the premium plugins you need:

```js
import 'tinymce-premium/plugins/advcode';
import 'tinymce-premium/plugins/tinycomments';
// Always include the licensekeymanager plugin when using premium plugins with a commercial license.
import 'tinymce-premium/plugins/licensekeymanager';
```
2. Add the plugins to your editor configuration:

```js
tinymce.init({
  selector: 'textarea',
  license_key: 'T8LK:...', // Your commercial license key
  plugins: 'advcode tinycomments',
  // ... other configuration
});
```
For complete bundling examples, see the [Premium plugins](#premium-plugins) and [Community plugins](#community-plugins) sections below.

### Loading with external_plugins

The `external_plugins` option loads plugins at runtime from a specified URL. This approach uses lazy loading, serving TinyMCE assets from a CDN or separate host, and avoids adding editor code to the application bundle. Tiny Cloud uses this approach to load the editor.

```js
tinymce.init({
  selector: 'textarea',
  license_key: 'T8LK:...', // Your commercial license key
  external_plugins: {
    'advcode': '/<path_to_premium_plugins>/advcode/plugin.min.js',
    'tinycomments': '/<path_to_premium_plugins>/tinycomments/plugin.min.js',
    // Always include the licensekeymanager plugin when using premium plugins with a commercial license.
    'licensekeymanager': '/<path_to_premium_plugins>/licensekeymanager/plugin.min.js'
  },
  plugins: 'advcode tinycomments',
  // ... other configuration
});
```

> **Note:** The `external_plugins` option supports three URL formats:
> 
> - Absolute URLs (e.g., `https://cdn.example.com/...`)
> - Relative to web-server root (e.g., `/node_modules/...`)
> - Relative to TinyMCE `base_url` (e.g., `../../node_modules/...`)
> For more information, see: [`external_plugins` configuration option](../editor-important-options/#external_plugins).

### Premium plugins

When bundling, replace the `plugincode` with the specific plugins in your TinyMCE configuration.

The `tinymce-premium` package is the recommended way to install and use premium plugins with TinyMCE. It includes all premium plugins, skins, icons, and language packs.

To bundle premium plugins from the NPM package, import the individual plugins you need.

**Module Syntax:** ES6+ · **Source:** NPM

**Example:**

```js
import 'tinymce-premium/plugins/advcode';
import 'tinymce-premium/plugins/tinycomments';
/* Always include the licensekeymanager plugin when using premium plugins with a commercial license. */
import 'tinymce-premium/plugins/licensekeymanager';
```
**Module Syntax:** ES6+ · **Source:** `.zip`

**Example:**

```js
import '<path_to_tinymce_premium_zip>/plugins/advcode';
```
**Module Syntax:** Common JS · **Source:** NPM

**Example:**

```js
require('tinymce-premium/plugins/advcode');
require('tinymce-premium/plugins/tinycomments');
/* Always include the licensekeymanager plugin when using premium plugins with a commercial license. */
require('tinymce-premium/plugins/licensekeymanager');
```
**Module Syntax:** Common JS · **Source:** `.zip`

**Example:**

```js
require('<path_to_tinymce_premium_zip>/plugins/advcode');
```
If premium skins and icons are required, you can import them from the `tinymce-premium` package:

```js
// Premium skins (oxide is the default skin)
import 'tinymce-premium/skins/ui/oxide/skin.css';

// Premium icons
import 'tinymce-premium/icons/premium';
```

> **Note:**
> - **Icons**: The default icon pack is always required. Premium icon packs may not include all icons and are designed to fall back to the default icons when they suit the pack. Import both the default and premium icon packs, then use the [`icons`](../editor-icons/) option in your editor configuration to tell TinyMCE to also use the premium icon pack.
> - **Skins**: Import either a community or premium skin (not both). Configure the skin using the [`skin`](../editor-skin/) option in your editor configuration.

> **Note:** Plugin language files (such as `./plugins/<plugincode>/langs/sv_SE.js`) are required where the editor user interface is localized using the [language option](../ui-localization/#language).
> 
> The below plugins require these [plugin-language-files](#plugin-language-files)
> 
> - AI Assistant (ai)
> - Accessibility Checker (a11ychecker)
> - Enhanced Code (advcode)
> - Enhanced Tables (advtable)
> - Templates (advtemplate)
> - Spelling Autocorrect (autocorrect)
> - Image Editing (editimage)
> - Export to PDF (exportpdf)
> - Export to Word (exportword)
> - Footnotes (footnotes)
> - Import from Word (importword)
> - Merge Tags (mergetags)
> - Page Embedding (pageembed)
> - PowerPaste (powerpaste)
> - Revision History (revisionhistory)
> - Table of Contents (tableofcontents)
> - Comments (tinycomments)
> - Spell Checker (tinymcespellchecker)
> - Typography (typography)

### Community plugins

When bundling, replace the `plugincode` with the specific plugins in your TinyMCE configuration.

> **Tip:** The below plugin also requires additional files to be included along side the [base folder](#base-folder).

#### Emoticons (`emoticons`)

Requires other js files
```js
./plugins/emoticons/js/emojiimages.js
./plugins/emoticons/js/emojis.js
```

> **Note:** Only one of the above `.js` files are required, depending on which one is chosen through the `emoticons_database` setting.

### Plugin language files

> **Important:** Replace `<plugincode>` placeholder with the specific `plugincode` when adding the plugin language files to your config.

```js
./plugins/<plugincode>/langs/ar.js
./plugins/<plugincode>/langs/bg_BG.js
./plugins/<plugincode>/langs/ca.js
./plugins/<plugincode>/langs/cs.js
./plugins/<plugincode>/langs/da.js
./plugins/<plugincode>/langs/de.js
./plugins/<plugincode>/langs/el.js
./plugins/<plugincode>/langs/es.js
./plugins/<plugincode>/langs/eu.js
./plugins/<plugincode>/langs/fa.js
./plugins/<plugincode>/langs/fi.js
./plugins/<plugincode>/langs/fr_FR.js
./plugins/<plugincode>/langs/he_IL.js
./plugins/<plugincode>/langs/hi.js
./plugins/<plugincode>/langs/hr.js
./plugins/<plugincode>/langs/hu_HU.js
./plugins/<plugincode>/langs/id.js
./plugins/<plugincode>/langs/it.js
./plugins/<plugincode>/langs/ja.js
./plugins/<plugincode>/langs/kk.js
./plugins/<plugincode>/langs/ko_KR.js
./plugins/<plugincode>/langs/ms.js
./plugins/<plugincode>/langs/nb_NO.js
./plugins/<plugincode>/langs/nl.js
./plugins/<plugincode>/langs/pl.js
./plugins/<plugincode>/langs/pt_BR.js
./plugins/<plugincode>/langs/pt_PT.js
./plugins/<plugincode>/langs/ro.js
./plugins/<plugincode>/langs/ru.js
./plugins/<plugincode>/langs/sk.js
./plugins/<plugincode>/langs/sl_SI.js
./plugins/<plugincode>/langs/sv_SE.js
./plugins/<plugincode>/langs/th_TH.js
./plugins/<plugincode>/langs/tr.js
./plugins/<plugincode>/langs/uk.js
./plugins/<plugincode>/langs/vi.js
./plugins/<plugincode>/langs/zh_CN.js
./plugins/<plugincode>/langs/zh_TW.js
```

### Bundling plugin language files

Plugin language files are separate from the main TinyMCE UI language files. Each plugin has its own language files located in `plugins/<plugincode>/langs/`.

- **Core UI language files**: Located in `langs/` (e.g., `tinymce-premium/langs/ar.js`)
- **Premium plugin language files**: Located in `plugins/<plugincode>/langs/` (e.g., `tinymce-premium/plugins/advcode/langs/ar.js`)

To bundle premium plugin language files, import them using the same module syntax as bundling plugins, but append `/langs/<language>.js` to the import path:

```js
// Import the plugin
import 'tinymce-premium/plugins/advcode';
// Import the premium plugin's Arabic language file
import 'tinymce-premium/plugins/advcode/langs/ar.js';
// Import the main UI Arabic language file (if needed)
import 'tinymce-premium/langs/ar.js';

tinymce.init({
  selector: 'textarea',
  language: 'ar',
  plugins: 'advcode',
  // ... other configuration
});
```

> **Note:** For premium plugins from `tinymce-premium`, the language file path must include the `.js` extension.

### Plugin lazy-loading and additional resources

> **Important:** Plugins lazy-load additional resources (JS and CSS files) at runtime for optimal performance. These resources must be:
> 
> - **Included in the bundle** along with the plugin (recommended for bundled applications)
> - **Placed as static assets** in the expected location (for non-bundled deployments)
> Missing resources may cause plugins to fail or display errors.
When bundling, explicitly import any additional resources that plugins require. The module bundler includes these files in the application bundle, making them available at runtime.

For non-bundled deployments using `external_plugins`, ensure all required resource files (CSS, JS, and language files) are accessible at the expected paths relative to the plugin file location.

See [Additional plugin resources](#plugin-resources) for specific examples of plugins that require additional resources.

## Additional plugin resources

> **Important:** When bundling TinyMCE with module loaders (Webpack, Vite, Rollup), some plugins require additional resource files (CSS, JS, or language files) to be explicitly imported. These files are not automatically resolved by the bundler and must be imported manually.
> 
> Key points:
> 
> - Core plugin resources typically use relative paths without file extensions
> - Premium plugin resources (from `tinymce-premium`) MUST include the `.js` or `.css` file extension in the import path
> - Language files are typically located in `plugins/<plugincode>/langs/`
> - CSS files may be in `plugins/<plugincode>/css/` or at the plugin root
> - English is the default language, so `en.js` language files don’t exist (plugins fall back to English)

### Common plugin resource requirements

The following plugins require additional resource files when bundling:

#### Help plugin (`help`)

The Help plugin requires the keyboard navigation language file for the keyboard navigation tab to function properly:

**Module Syntax:** ES6+ · **Source:** npm

**Example:**

```js
import 'tinymce/plugins/help/js/i18n/keynav/en';
```
**Module Syntax:** ES6+ · **Source:** `.zip`

**Example:**

```js
import '../tinymce/plugins/help/js/i18n/keynav/en';
```
**Module Syntax:** Common JS · **Source:** npm

**Example:**

```js
require('tinymce/plugins/help/js/i18n/keynav/en');
```
**Module Syntax:** Common JS · **Source:** `.zip`

**Example:**

```js
require('../tinymce/plugins/help/js/i18n/keynav/en');
```

#### Page Embed plugin (`pageembed`)

The Page Embed plugin requires a CSS file for proper styling:

**Module Syntax:** ES6+ · **Source:** npm

**Example:**

```js
import 'tinymce-premium/plugins/pageembed/css/empa30.css';
```
**Module Syntax:** ES6+ · **Source:** `.zip`

**Example:**

```js
import '../plugins/pageembed/css/empa30.css';
```
**Module Syntax:** Common JS · **Source:** npm

**Example:**

```js
require('tinymce-premium/plugins/pageembed/css/empa30.css');
```
**Module Syntax:** Common JS · **Source:** `.zip`

**Example:**

```js
require('../plugins/pageembed/css/empa30.css');
```

#### Emoticons plugin (`emoticons`)

The [Emoticons plugin](../emoticons/) requires an emoji database file. By default, it uses `js/emojis.js`, but you can also use `js/emojiimages.js` by configuring the [`emoticons_database`](../emoticons/#emoticons_database) option.

**Module Syntax:** ES6+ · **Source:** npm

**Example:**

```js
import 'tinymce/plugins/emoticons/js/emojis';
```
**Module Syntax:** ES6+ · **Source:** `.zip`

**Example:**

```js
import '../tinymce/plugins/emoticons/js/emojis';
```
**Module Syntax:** Common JS · **Source:** npm

**Example:**

```js
require('tinymce/plugins/emoticons/js/emojis');
```
**Module Syntax:** Common JS · **Source:** `.zip`

**Example:**

```js
require('../tinymce/plugins/emoticons/js/emojis');
```

#### Spelling Autocorrect plugin (`autocorrect`)

The [Spelling Autocorrect plugin](../autocorrect/) requires a word list file. English is the only supported language.

**Module Syntax:** ES6+ · **Source:** npm

**Example:**

```js
import 'tinymce-premium/plugins/autocorrect/js/en.js';
```
**Module Syntax:** ES6+ · **Source:** `.zip`

**Example:**

```js
import '../plugins/autocorrect/js/en.js';
```
**Module Syntax:** Common JS · **Source:** npm

**Example:**

```js
require('tinymce-premium/plugins/autocorrect/js/en.js');
```
**Module Syntax:** Common JS · **Source:** `.zip`

**Example:**

```js
require('../plugins/autocorrect/js/en.js');
```

#### Media Optimizer plugin (`uploadcare`)

The [Media Optimizer plugin](../uploadcare/) requires a webcomponent file for video functionality. The `uc-video.js` file is needed when using the video features of the plugin.

**Module Syntax:** ES6+ · **Source:** npm

**Example:**

```js
import 'tinymce-premium/plugins/uploadcare/js/uc-video.js';
```
**Module Syntax:** ES6+ · **Source:** `.zip`

**Example:**

```js
import '../plugins/uploadcare/js/uc-video.js';
```
**Module Syntax:** Common JS · **Source:** npm

**Example:**

```js
require('tinymce-premium/plugins/uploadcare/js/uc-video.js');
```
**Module Syntax:** Common JS · **Source:** `.zip`

**Example:**

```js
require('../plugins/uploadcare/js/uc-video.js');
```
