Modern rich-text editing engine for web applications.
Modular, framework-agnostic, and MIT licensed. Ship a full editor with themes and toolbar modules, or compose custom builds from lextrix-change, lextrix-dom, lextrix-core, and lextrix-formats.
Documentation · Quick start · Architecture · Issues
- Modular — Use the full
lextrixbundle or assemble only the packages you need. - Extensible — Register custom formats, modules, and embeds through a central registry.
- Framework agnostic — Works with React, Vue, Angular, Svelte, or vanilla JavaScript.
- Plugin friendly — Clipboard, keyboard, history, toolbar, tables, syntax, and image resize as modules.
- TypeScript-first — Written in TypeScript with a typed monorepo and stable public APIs.
- Predictable changes — Document updates flow through ChangeSets with compose, diff, transform, and invert.
- Themes — Snow, Bubble, Slate, and Dawn (CSS included)
- Toolbar — Configurable formatting controls or your own DOM toolbar
- Rich formats — Bold, lists, headers, links, code blocks, tables, images, video, formulas
- Clipboard — HTML paste normalization (Word, Google Docs, custom matchers)
- Keyboard — Shortcuts for lists, headers, links, and custom bindings
- History — Undo / redo with configurable merge delay
- Image resize — Drag handles on selected images
- Syntax highlighting — Code blocks with highlight.js
- ChangeSet API — JSON operations compatible with common OT conventions
- Custom builds — Register blots, formats, modules, UI, and themes à la carte
npm install lextrixpnpm add lextrixyarn add lextrixbun add lextrixPeer dependencies (optional): highlight.js for syntax, KaTeX for formulas.
<div id="editor"></div>import Lextrix from 'lextrix';
import 'lextrix/snow.css';
const editor = new Lextrix('#editor', {
theme: 'snow',
placeholder: 'Start writing…',
modules: {
toolbar: [
['bold', 'italic', 'underline'],
[{ header: [1, 2, false] }],
[{ list: 'ordered' }, { list: 'bullet' }],
['link', 'image'],
['clean'],
],
imageResize: true,
},
});
editor.setContents([
{ insert: 'Hello Lextrix\n', attributes: { header: 1 } },
{ insert: 'Edit rich text with themes, modules, and ChangeSets.\n' },
]);Listen for changes:
editor.on('text-change', (changeSet, oldChangeSet, source) => {
if (source === 'user') {
save(editor.getContents());
}
});More examples: docs/getting-started/quick-start.md
Lextrix separates change processing, document structure, DOM synchronization, formatting, selection, and plugins into dedicated packages.
User Input → Selection → Commands → Change Engine → Document Model → DOM Sync → Browser
Read the full guide: Architecture overview
| Package | Role |
|---|---|
lextrix |
Published bundle (UMD + CSS) |
lextrix-change |
ChangeSet / operational transform |
lextrix-dom |
Blots, registry, DOM sync |
lextrix-core |
Editor shell, selection |
lextrix-formats |
Built-in formats |
lextrix-modules |
Clipboard, keyboard, toolbar, … |
lextrix-ui |
Toolbar widgets |
lextrix-themes |
Snow, bubble, slate, dawn |
Modules extend the editor through PluginHost — clipboard, keyboard, history, uploader, toolbar, syntax, tables, and custom plugins.
import { lxrPath } from 'lextrix-core/registry-paths.js';
Lextrix.register({ [lxrPath.module('wordCount')]: WordCountModule });
new Lextrix('#editor', {
theme: 'snow',
modules: { wordCount: true },
});Guide: Plugin author guide · Modules
Register inline, block, and embed formats with helpers and Lextrix.register():
import { lxrPath } from 'lextrix-core/registry-paths.js';
import { defineInlineTagFormat } from 'lextrix-formats/inline-format.js';
const Highlight = defineInlineTagFormat({ blotName: 'highlight', tagName: 'MARK' });
Lextrix.register({ [lxrPath.format('highlight')]: Highlight });Guides: Formats · Custom embeds · Registry
new Lextrix('#editor', {
theme: 'bubble',
modules: {
toolbar: [['bold', 'italic', 'link'], [{ header: 1 }, { header: 2 }]],
},
});new Lextrix('#editor', { theme: 'snow', readOnly: true });import Lextrix, { registerBlots } from 'lextrix-core';
import { registerFormats } from 'lextrix-formats';
import { registerCoreModules, registerOptionalModules } from 'lextrix-modules';
import { registerUI } from 'lextrix-ui';
import { registerThemes } from 'lextrix-themes';
registerBlots(Lextrix);
registerFormats(Lextrix);
registerCoreModules(Lextrix);
registerOptionalModules(Lextrix);
registerUI(Lextrix);
registerThemes(Lextrix);Run the local demo: npm run dev → http://localhost:5173
| Topic | Link |
|---|---|
| Index | docs/README.md |
| Installation | getting-started/installation.md |
| Configuration | guides/configuration.md |
| API reference | api/reference.md |
| ChangeSet / OT | guides/change-set.md |
| Architecture | architecture/overview.md |
| Plugins | guides/plugins.md |
| Formats | guides/formats.md |
- Public live playground and hosted demo
- Framework starter templates (React, Vue)
- Published TypeScript types on npm
- Expanded plugin cookbook and embed examples
- Bundle size benchmarks in docs
- Optional collaboration examples built on ChangeSet transform
git clone https://github.com/rishureetesh/lextrix.git
cd lextrix
npm install
npm run build
npm run dev # Vite demo → http://localhost:5173
npm testContributing: .github/CONTRIBUTING.md · Monorepo guide: .github/DEVELOPMENT.md
MIT © Reetesh. See LICENSE. Runtime dependencies: NOTICE.md.