npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@editora/plugins

v1.0.12

Published

Enterprise plugin suite for Editora rich text editor in React and web apps, including tables, media, workflow, and compliance tooling.

Downloads

262

Readme

@editora/plugins

[!IMPORTANT] Live Website: https://editora-ecosystem.netlify.app/
Storybook: https://editora-ecosystem-storybook.netlify.app/

Comprehensive plugin collection for Editora Rich Text Editor with 40+ plugins for text formatting, media management, accessibility, and more.

📦 Installation

npm install @editora/plugins @editora/core @editora/themes

When using plugin UI features (table toolbar, pickers, dialogs), also import:

import "@editora/plugins/styles.css";

🎯 Overview

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.

✨ Plugin Categories

Text Formatting (12 plugins)

  • Bold, Italic, Underline, Strikethrough
  • Font Family, Font Size, Text Color, Background Color
  • Subscript, Superscript, Code Inline
  • Clear Formatting

Block Elements (8 plugins)

  • Headings (H1-H6)
  • Paragraphs
  • Blockquotes
  • Code Blocks with syntax highlighting
  • Horizontal Rules
  • Page Breaks
  • Preformatted Text
  • Footnotes

Lists & Structure (5 plugins)

  • Bullet Lists
  • Numbered Lists
  • Checklists
  • Indent/Outdent
  • Text Alignment (Left, Center, Right, Justify)

Media & Embeds (6 plugins)

  • Images with upload
  • Videos
  • Audio
  • Embed IFrames
  • Media Manager
  • Special Characters & Emojis

Advanced Features (10 plugins)

  • Tables (full editing capabilities)
  • Math Equations (LaTeX support)
  • Merge Tags / Templates
  • Comments & Annotations
  • Document Manager (import/export)
  • Spell Checker
  • Accessibility Checker
  • Link Management
  • Anchor Links
  • Print Preview

Utilities (4 plugins)

  • History (Undo/Redo)
  • Fullscreen Mode
  • Line Height
  • Text Direction (LTR/RTL)
  • Capitalization (uppercase, lowercase, title case)

🚀 Quick Start

Entry Paths (All Free + Customizable)

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 imports

Recommended Imports For Smaller Bundles

For 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');

Enterprise Preset Details

@editora/plugins/enterprise includes advanced plugins for governance, compliance, workflow, and QA:

  • Collaboration/workflow: TrackChangesPlugin, VersionDiffPlugin, CommentsPlugin, ApprovalWorkflowPlugin
  • Validation/compliance: ContentRulesPlugin, DocSchemaPlugin, A11yCheckerPlugin, SpellCheckPlugin, PIIRedactionPlugin
  • Structured/dynamic authoring: ConditionalContentPlugin, DataBindingPlugin, MergeTagPlugin, TemplatePlugin, CitationsPlugin
  • Productivity/runtime intelligence: SmartPastePlugin, SlashCommandsPlugin, MentionPlugin, BlocksLibraryPlugin, TranslationWorkflowPlugin
  • Manager-backed advanced plugins: MediaManagerPlugin, DocumentManagerPlugin

Basic Formatting

import {
  BoldPlugin,
  ItalicPlugin,
  UnderlinePlugin,
  StrikethroughPlugin
} from '@editora/plugins';

import "@editora/plugins/styles.css";
import "@editora/themes/themes/default.css";
const plugins = [
  BoldPlugin(),
  ItalicPlugin(),
  UnderlinePlugin(),
  StrikethroughPlugin()
];

Complete Editor Setup

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()
];

📖 Plugin API Reference

Text Formatting Plugins

Bold Plugin

BoldPlugin(options?: {
  keyboard?: string; // Default: 'Mod-b'
  icon?: ReactNode;
  className?: string;
})

Font Family Plugin

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' }
  ]
});

Font Size Plugin

FontSizePlugin(options?: {
  sizes?: string[]; // Default: ['8pt', '10pt', '12pt', '14pt', '18pt', '24pt', '36pt']
  defaultSize?: string;
})

Text Color Plugin

TextColorPlugin(options?: {
  colors?: string[];
  customColors?: boolean;
  recentColors?: boolean;
})

Block Element Plugins

Heading Plugin

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'
  }
});

Code Sample Plugin

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
});

List Plugins

List Plugin

ListPlugin(options?: {
  bulletList?: boolean;
  orderedList?: boolean;
  keyboard?: {
    bullet?: string; // Default: 'Mod-Shift-8'
    ordered?: string; // Default: 'Mod-Shift-7'
  };
})

Checklist Plugin

ChecklistPlugin(options?: {
  nested?: boolean;
  keyboard?: string;
})

Media Plugins

Image Plugin

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
});

Link Plugin

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
});

Advanced Plugins

Table Plugin

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
});

Math Plugin

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}'
  }
});

Comments Plugin

CommentsPlugin(options?: {
  onCommentAdd?: (comment: Comment) => void;
  onCommentEdit?: (comment: Comment) => void;
  onCommentDelete?: (commentId: string) => void;
  onCommentResolve?: (commentId: string) => void;
  showResolved?: boolean;
})

Document Manager Plugin

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'
});

Spell Check Plugin

SpellCheckPlugin(options?: {
  language?: string; // Default: 'en-US'
  customDictionary?: string[];
  ignoreUppercase?: boolean;
  ignoreNumbers?: boolean;
})

Accessibility Checker Plugin

A11yCheckerPlugin(options?: {
  rules?: string[];
  autoCheck?: boolean;
  severity?: 'error' | 'warning' | 'info';
})

Utility Plugins

History Plugin

HistoryPlugin(options?: {
  depth?: number; // Default: 100
  keyboard?: {
    undo?: string; // Default: 'Mod-z'
    redo?: string; // Default: 'Mod-Shift-z'
  };
})

Fullscreen Plugin

FullscreenPlugin(options?: {
  keyboard?: string; // Default: 'F11'
  onEnter?: () => void;
  onExit?: () => void;
})

💡 Usage Examples

Blog Editor

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()
];

Technical Documentation Editor

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()
];

Collaborative Editor

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 order
  • defaultCategory: initial tab
  • dialog: labels/placeholders/preview toggle
  • tokenTemplate: string template ({key}, {label}, {category}, {value}) or formatter function

Custom Templates

You 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.
  • HTML is sanitized on insertion.
  • Use validateTemplate(template) if you want to pre-check templates before registering.

🔧 TypeScript Support

All plugins include full TypeScript definitions:

import type { Plugin, PluginConfig } from '@editora/plugins';

const customConfig: PluginConfig = {
  // Full type safety
};

📄 License

MIT © Ajay Kumar

🔗 Links