mogul-text-editor
v0.6.0
Published
Schema-first, headless, block-based rich text editor for React.
Maintainers
Readme
mogul-text-editor
"Rich" → "Mogul" — a schema-first, headless, block-based rich text editor for React.
A React library for editing structured, block-based documents (Notion-like, with section structure derived from heading levels).
Philosophy
- Schema-first — the document is plain JSON. Blocks store intent (e.g.
{ type: "heading", level: 2 }), not styling. - Headless by design — an optional stylesheet (
styles.css,.wte-*classes) ships with it, but the host owns the look (Tailwind, custom CSS, or the bundled theme). - Clear layers — schema → commands → hooks → components → exporters. Each is usable on its own.
- Predictable — explicit operations via
editor.commands.*, never direct mutation. - Native-first input — the browser paints typing; the model is read back from the DOM, so the caret is never disturbed while you type.
- React-free core — the root entry is server-safe (apply LLM patches, validate, export without React).
Install
pnpm add mogul-text-editor
# only if you use the docx exporter:
pnpm add docxPeer dependencies: react and react-dom (>= 19). docx is an optional peer dependency needed
only by mogul-text-editor/export-docx.
Quick start
import { useState } from 'react';
import { createEmptyDocument } from 'mogul-text-editor';
import { DocumentEditor } from 'mogul-text-editor/react';
import 'mogul-text-editor/styles.css';
function App() {
const [doc, setDoc] = useState(createEmptyDocument());
return (
<DocumentEditor
value={doc}
onChange={setDoc}
onCommit={(committed) => save(committed)}
/>
);
}onChange fires on every transaction; onCommit fires when focus leaves the editor, after an
idle pause, or after an explicit commit. Passing a genuinely new value swaps the document;
echoing back what you got from onChange is a no-op, so controlled usage is safe.
Features
- Per-line native editing with directional text selection across blocks, rich clipboard operations, and separate whole-block selection via drag handles.
Enter/Backspace/Tabstructure (split, merge, indent);Enteron an empty list item exits the list.- Markdown input rules (
#,-,1.) and a/slash menu. - Floating mark toolbar, hierarchical heading numbering, collapsible sections.
- First-class image blocks with URL or host asset references; images are user-supplied via paste/drop, and the
/image rowcommand lays out an empty grid of drop slots to fill. {{label}}→ placeholder chips; a full plugin system for custom blocks, inline-object chips, slash items, and toolbar buttons.- Rich paste from Word / Google Docs / the web, including URL-backed
<img>/<figure>content. - Exporters to HTML, Markdown, and docx.
- i18n (
endefault,pt-BRbuilt in) and a headless, server-safe core.
Entry points
| Entry | Contents |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| mogul-text-editor | React-free core: schema, factories, the headless engine, transforms, the patch pipeline (D10), sections, numbering, serialization. Server-safe. |
| mogul-text-editor/react | Hooks (useDocumentEditor, useBlockEditor), components (DocumentEditor, BlockEditor), the plugin system, paste, and i18n. |
| mogul-text-editor/export-html | exportHtml |
| mogul-text-editor/export-markdown | exportMarkdown |
| mogul-text-editor/export-docx | exportDocx (needs the docx peer dep) |
| mogul-text-editor/styles.css | Optional default theme |
Documentation
- Getting started
- Concepts & data model
- API reference
- Plugins
- Exporters
- Internationalization
- Headless & server use
- Styling
- Stability & versioning
See also ARCHITECTURE.md for the design decisions (D1–D16) and ROADMAP.md for status.
Status
0.5.x (pre-1.0): published on npm's latest channel while the public API is finalized toward 1.0. See
Stability & versioning for what's covered by semver.
License
MIT
