Skip to main content
Lumen Editor’s plugin system lets you extend the editor with your own behavior — status bars, word counts, character limits, custom keyboard shortcuts, analytics hooks, and more — without forking or monkey-patching the core library. A plugin is just a plain function, so there’s nothing new to learn: if you can write JavaScript, you can write a plugin.

Plugin shape

A plugin is a function that receives the editor instance and returns nothing:
That’s the entire contract. You can read from the editor, write to the DOM, subscribe to events, or call any public editor method — all from within that single function. There are no lifecycle hooks, no class to extend, and no registration API beyond passing your function to the plugins option.
Plugins run after the editor has fully mounted and its DOM is ready. This means editor.root is available and all built-in modules have already been initialized when your plugin function executes.

Full example: word count plugin

The following plugin appends a live word-count display beneath the editor and updates it on every change:

Accessing the DOM

Inside your plugin, editor.root is the live contenteditable element that the editor manages. You can append child elements to it, add event listeners, or read its innerHTML and textContent:
Avoid mutating editor.root.innerHTML directly — doing so bypasses the editor’s internal state and history stack, which can lead to inconsistent undo/redo behavior. Use the editor’s public API methods instead when you need to change content programmatically.

Subscribing to events

Use editor.on(eventName, handler) inside your plugin to react to editor events. All of the editor’s built-in events are available:

Installing plugins

You can install plugins in two ways:
1

Via the plugins option at initialization

Pass an array of plugin functions to the plugins option. All plugins in the array run once, in order, after the editor mounts:
2

Via editor.use() after initialization

Call editor.use(plugin) at any point after the editor has been constructed. The plugin function runs immediately:
For reusable plugins that accept configuration, wrap them in a factory function that returns the (editor) => void function. For example: createWordCount({ className: 'my-wc' }) returns a configured plugin function you can pass directly to the plugins array.