
Company News
Andrew Becherer Joins Socket as Chief Information Security Officer
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.
@editora/plugins
Advanced tools
Enterprise plugin suite for Editora rich text editor in React and web apps, including tables, media, workflow, and compliance tooling.
[!IMPORTANT] Live Website: https://editora-ecosystem.netlify.app/
Storybook: https://editora-ecosystem-storybook.netlify.app/
Comprehensive plugin collection with 40+ plugins for rich text editing
Comprehensive plugin collection for Editora Rich Text Editor with 40+ plugins for text formatting, media management, accessibility, and more.
npm install @editora/plugins @editora/core @editora/themes
When using plugin UI features (table toolbar, pickers, dialogs), also import:
import "@editora/plugins/styles.css";
This package provides a complete set of plugins for building feature-rich text editors. Each plugin is modular, tree-shakeable, and can be used independently.
Every plugin entry path is MIT-licensed, free to use, and customizable:
@editora/plugins: full plugin catalog@editora/plugins/lite: common/core plugin subset for lean bundles@editora/plugins/enterprise: advanced/specialized workflow plugins@editora/plugins/<plugin-name>: targeted per-plugin importsFor best bundle size, avoid importing everything from @editora/plugins in large apps.
Use one of these patterns:
// Lightweight preset entry
import { BoldPlugin, ItalicPlugin, HistoryPlugin } from '@editora/plugins/lite';
// Enterprise preset entry (advanced/specialized plugins)
import { MentionPlugin, TrackChangesPlugin, SmartPastePlugin } from '@editora/plugins/enterprise';
// Per-plugin subpath entry (most explicit)
import { BoldPlugin } from '@editora/plugins/bold';
import { ItalicPlugin } from '@editora/plugins/italic';
import { SpellCheckPlugin } from '@editora/plugins/spell-check';
Lazy-load heavy plugins only when needed:
const { DocumentManagerPlugin } = await import('@editora/plugins/document-manager');
const { MediaManagerPlugin } = await import('@editora/plugins/media-manager');
const { SpellCheckPlugin } = await import('@editora/plugins/spell-check');
@editora/plugins/enterprise includes advanced plugins for governance, compliance, workflow, and QA:
TrackChangesPlugin, VersionDiffPlugin, CommentsPlugin, ApprovalWorkflowPluginContentRulesPlugin, DocSchemaPlugin, A11yCheckerPlugin, SpellCheckPlugin, PIIRedactionPluginConditionalContentPlugin, DataBindingPlugin, MergeTagPlugin, TemplatePlugin, CitationsPluginSmartPastePlugin, SlashCommandsPlugin, MentionPlugin, BlocksLibraryPlugin, TranslationWorkflowPluginMediaManagerPlugin, DocumentManagerPluginimport {
BoldPlugin,
ItalicPlugin,
UnderlinePlugin,
StrikethroughPlugin
} from '@editora/plugins';
import "@editora/plugins/styles.css";
import "@editora/themes/themes/default.css";
const plugins = [
BoldPlugin(),
ItalicPlugin(),
UnderlinePlugin(),
StrikethroughPlugin()
];
import {
// Text formatting
BoldPlugin,
ItalicPlugin,
UnderlinePlugin,
FontFamilyPlugin,
FontSizePlugin,
TextColorPlugin,
BackgroundColorPlugin,
// Block elements
HeadingPlugin,
BlockquotePlugin,
CodeSamplePlugin,
// Lists
ListPlugin,
ChecklistPlugin,
IndentPlugin,
TextAlignmentPlugin,
// Media
LinkPlugin,
TablePlugin,
MediaManagerPlugin,
// Advanced
MathPlugin,
CommentsPlugin,
HistoryPlugin,
FullscreenPlugin,
DocumentManagerPlugin
} from '@editora/plugins';
const plugins = [
// Text formatting
BoldPlugin(),
ItalicPlugin(),
UnderlinePlugin(),
FontFamilyPlugin(),
FontSizePlugin(),
TextColorPlugin(),
BackgroundColorPlugin(),
// Block elements
HeadingPlugin(),
BlockquotePlugin(),
CodeSamplePlugin(),
// Lists
ListPlugin(),
ChecklistPlugin(),
IndentPlugin(),
TextAlignmentPlugin(),
// Media
LinkPlugin(),
TablePlugin(),
MediaManagerPlugin(),
// Advanced
MathPlugin(),
CommentsPlugin(),
HistoryPlugin(),
FullscreenPlugin(),
DocumentManagerPlugin()
];
BoldPlugin(options?: {
keyboard?: string; // Default: 'Mod-b'
icon?: ReactNode;
className?: string;
})
FontFamilyPlugin(options?: {
fonts?: Array<{
name: string;
value: string;
fallback?: string;
}>;
defaultFont?: string;
})
// Example
const fontFamilyPlugin = FontFamilyPlugin({
fonts: [
{ name: 'Arial', value: 'Arial, sans-serif' },
{ name: 'Times New Roman', value: 'Times New Roman, serif' },
{ name: 'Courier New', value: 'Courier New, monospace' }
]
});
FontSizePlugin(options?: {
sizes?: string[]; // Default: ['8pt', '10pt', '12pt', '14pt', '18pt', '24pt', '36pt']
defaultSize?: string;
})
TextColorPlugin(options?: {
colors?: string[];
customColors?: boolean;
recentColors?: boolean;
})
HeadingPlugin(options?: {
levels?: number[]; // Default: [1, 2, 3, 4, 5, 6]
defaultLevel?: number;
keyboard?: Record<number, string>;
})
// Example
const headingPlugin = HeadingPlugin({
levels: [1, 2, 3],
keyboard: {
1: 'Mod-Alt-1',
2: 'Mod-Alt-2',
3: 'Mod-Alt-3'
}
});
CodeSamplePlugin(options?: {
languages?: Array<{
name: string;
value: string;
}>;
theme?: 'light' | 'dark' | 'github' | 'monokai';
lineNumbers?: boolean;
highlightActiveLine?: boolean;
})
// Example
const codeSamplePlugin = CodeSamplePlugin({
languages: [
{ name: 'JavaScript', value: 'javascript' },
{ name: 'TypeScript', value: 'typescript' },
{ name: 'Python', value: 'python' },
{ name: 'HTML', value: 'html' },
{ name: 'CSS', value: 'css' }
],
theme: 'github',
lineNumbers: true
});
ListPlugin(options?: {
bulletList?: boolean;
orderedList?: boolean;
keyboard?: {
bullet?: string; // Default: 'Mod-Shift-8'
ordered?: string; // Default: 'Mod-Shift-7'
};
})
ChecklistPlugin(options?: {
nested?: boolean;
keyboard?: string;
})
MediaManagerPlugin(options: {
upload: (file: File) => Promise<string>;
validate?: (file: File) => boolean;
maxSize?: number; // bytes
allowedTypes?: string[];
resize?: boolean;
maxWidth?: number;
maxHeight?: number;
quality?: number; // 0-1
})
// Example
const imagePlugin = MediaManagerPlugin({
upload: async (file) => {
const formData = new FormData();
formData.append('image', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
return data.url;
},
maxSize: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
resize: true,
maxWidth: 1200,
quality: 0.9
});
LinkPlugin(options?: {
openOnClick?: boolean;
validate?: (url: string) => boolean;
onLinkClick?: (url: string) => void;
targetBlank?: boolean;
nofollow?: boolean;
})
// Example
const linkPlugin = LinkPlugin({
openOnClick: false,
validate: (url) => {
return url.startsWith('http://') || url.startsWith('https://');
},
onLinkClick: (url) => {
window.open(url, '_blank', 'noopener,noreferrer');
},
targetBlank: true
});
TablePlugin(options?: {
allowResize?: boolean;
defaultRows?: number;
defaultCols?: number;
maxRows?: number;
maxCols?: number;
cellSelection?: boolean;
headerRow?: boolean;
})
// Example
const tablePlugin = TablePlugin({
allowResize: true,
defaultRows: 3,
defaultCols: 3,
maxRows: 20,
maxCols: 10,
cellSelection: true,
headerRow: true
});
MathPlugin(options?: {
engine?: 'katex' | 'mathjax';
inline?: boolean;
display?: boolean;
macros?: Record<string, string>;
})
// Example
const mathPlugin = MathPlugin({
engine: 'katex',
inline: true,
display: true,
macros: {
'\\R': '\\mathbb{R}',
'\\N': '\\mathbb{N}'
}
});
CommentsPlugin(options?: {
onCommentAdd?: (comment: Comment) => void;
onCommentEdit?: (comment: Comment) => void;
onCommentDelete?: (commentId: string) => void;
onCommentResolve?: (commentId: string) => void;
showResolved?: boolean;
})
DocumentManagerPlugin(options?: {
export?: {
word?: boolean;
pdf?: boolean;
html?: boolean;
markdown?: boolean;
};
import?: {
word?: boolean;
html?: boolean;
markdown?: boolean;
};
fileName?: string;
})
// Example
const documentManagerPlugin = DocumentManagerPlugin({
export: {
word: true,
pdf: true,
html: true
},
fileName: 'document'
});
SpellCheckPlugin(options?: {
language?: string; // Default: 'en-US'
customDictionary?: string[];
ignoreUppercase?: boolean;
ignoreNumbers?: boolean;
})
A11yCheckerPlugin(options?: {
rules?: string[];
autoCheck?: boolean;
severity?: 'error' | 'warning' | 'info';
})
HistoryPlugin(options?: {
depth?: number; // Default: 100
keyboard?: {
undo?: string; // Default: 'Mod-z'
redo?: string; // Default: 'Mod-Shift-z'
};
})
FullscreenPlugin(options?: {
keyboard?: string; // Default: 'F11'
onEnter?: () => void;
onExit?: () => void;
})
import {
BoldPlugin,
ItalicPlugin,
HeadingPlugin,
ParagraphPlugin,
LinkPlugin,
MediaManagerPlugin,
ListPlugin,
BlockquotePlugin,
HistoryPlugin
} from '@editora/plugins';
const blogPlugins = [
BoldPlugin(),
ItalicPlugin(),
HeadingPlugin({ levels: [1, 2, 3] }),
LinkPlugin({ targetBlank: true }),
MediaManagerPlugin({
upload: uploadImage,
maxSize: 2 * 1024 * 1024
}),
ListPlugin(),
BlockquotePlugin(),
HistoryPlugin()
];
import {
BoldPlugin,
ItalicPlugin,
CodePlugin,
CodeSamplePlugin,
HeadingPlugin,
TablePlugin,
LinkPlugin,
AnchorPlugin,
MathPlugin,
HistoryPlugin
} from '@editora/plugins';
const docsPlugins = [
BoldPlugin(),
ItalicPlugin(),
CodePlugin(),
CodeSamplePlugin({
languages: [
{ name: 'JavaScript', value: 'javascript' },
{ name: 'TypeScript', value: 'typescript' },
{ name: 'Python', value: 'python' }
],
lineNumbers: true
}),
HeadingPlugin(),
TablePlugin({ headerRow: true }),
LinkPlugin(),
AnchorPlugin(),
MathPlugin({ engine: 'katex' }),
HistoryPlugin()
];
import {
BoldPlugin,
ItalicPlugin,
CommentsPlugin,
HistoryPlugin,
MergeTagPlugin
} from '@editora/plugins';
const collaborativePlugins = [
BoldPlugin(),
ItalicPlugin(),
CommentsPlugin({
onCommentAdd: async (comment) => {
await saveComment(comment);
},
onCommentResolve: async (commentId) => {
await resolveComment(commentId);
}
}),
MergeTagPlugin({
tags: [
{ label: 'First Name', value: '{{firstName}}', category: 'User' },
{ label: 'Last Name', value: '{{lastName}}', category: 'User' },
{ label: 'Email', value: '{{email}}', category: 'User' }
],
defaultCategory: 'User',
dialog: {
title: 'Insert Variable',
searchPlaceholder: 'Search variables...',
showPreview: true
},
tokenTemplate: '{value}'
}),
HistoryPlugin()
];
MergeTagPlugin supports functional customization:
tags: flat list of tags (auto-grouped by category)categories: explicit grouped categories with custom orderdefaultCategory: initial tabdialog: labels/placeholders/preview toggletokenTemplate: string template ({key}, {label}, {category}, {value}) or formatter functionYou can register your own templates before initializing the editor:
import { TemplatePlugin, addCustomTemplate } from '@editora/plugins';
addCustomTemplate({
id: 'invoice-basic',
name: 'Invoice (Basic)',
category: 'Billing',
description: 'Simple invoice template',
html: `
<h1>Invoice</h1>
<p><strong>Customer:</strong> {{customer.name}}</p>
<p><strong>Date:</strong> {{today}}</p>
<p><strong>Total:</strong> {{invoice.total}}</p>
`,
tags: ['invoice', 'billing']
});
const plugins = [
TemplatePlugin()
];
Notes:
id must be unique.validateTemplate(template) if you want to pre-check templates before registering.All plugins include full TypeScript definitions:
import type { Plugin, PluginConfig } from '@editora/plugins';
const customConfig: PluginConfig = {
// Full type safety
};
MIT © Ajay Kumar
FAQs
Enterprise plugin suite for Editora rich text editor in React and web apps, including tables, media, workflow, and compliance tooling.
The npm package @editora/plugins receives a total of 50 weekly downloads. As such, @editora/plugins popularity was classified as not popular.
We found that @editora/plugins demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.

Company News
Replit is integrating Socket Firewall into its AI-powered development experience to help protect builders from malicious open source packages.

Security News
npm confirmed a tooling bug incorrectly marked several one-character packages as security holders and said it was working on a rollback.