Better Rich Text Buy licence

Introduction

On this page
  1. Quick start
  2. Presets
  3. Packages
  4. Headless use
  5. Extending
  6. Bundle size

An embeddable rich text editor written in TypeScript. It has its own document engine, a default interface, a headless API and adapters for the common frameworks. Everything runs in your app with no licence server, load metering or required hosted service.

Quick start

TypeScript
import { createRichTextEditor } from '@better-rich-text/core';

const editor = createRichTextEditor('#editor', {
  content: '<p>Hello</p>',
  placeholder: 'Start writing…',
  onChange: (instance) => save(instance.getHTML()),
});

createRichTextEditor accepts a selector, an element or a <textarea> (which it keeps in sync for form posts). Use mode: 'inline' to edit an element in place, or mode: 'bare' for the editing surface without chrome.

Presets

The default is the standard preset. @better-rich-text/presets adds ready-made ones for long documents, collaboration, email and demos, each imported from its own subpath so you only bundle the one you use:

TypeScript
import { documentPreset } from '@better-rich-text/presets/document';

createRichTextEditor('#editor', { preset: documentPreset });

See docs/presets.md for what each preset includes, its size, and how to trim or extend it.

Packages

PackagePurpose
model Immutable document tree, schema, runtime validation, Unicode helpers, JSON envelope
engine Transactions, typed commands, plugins, history, filters and actions, statistics, tool definitions
dom Browser view: rendering, selection, input, composition, clipboard, decorations
ui Toolbar, menus, dialogs, status bar and opt-in features
skins Visual skins (studio default; others load on demand)
core Presets and createRichTextEditor
presets Document, collaboration, email and full presets (see docs/presets.md)
format-html, format-markdown Import and export
plugin-* Marks, blocks, links, lists, code blocks, text style, images, image editing, tables, search, paste cleanup, typography and autocorrect, format painter, styles, page breaks, templates, files, limits, saving, proofing and more
react, vue, angular, svelte, aurelia, solid, web-component, legacy Framework adapters (see docs/frameworks.md)

Headless use

The engine has no DOM dependency, so the same commands run on a server or in a worker:

TypeScript
import { createEditor } from '@better-rich-text/engine';
import { marksPlugin } from '@better-rich-text/plugin-marks';

const editor = createEditor({ plugins: [marksPlugin] });
editor.execute('text.insert', { text: 'Hello' });
editor.execute('selection.selectAll');
editor.execute('format.toggleBold');

Command names and inputs are typed from the installed plugins, and the same schemas validate input at runtime.

Extending

Plugins declare nodes, marks, commands, key bindings, input rules and normalisers. Beyond events, every layer exposes filters and actions with priorities and namespaces, like WordPress hooks:

TypeScript
editor.hooks.addFilter('content.insertText', (text) => text.replace(/--/g, '\u2013'), { namespace: 'my-plugin' });
editor.hooks.addAction('transaction.committed', (event) => audit(event), { namespace: 'my-plugin' });

See docs/adr/0003-filters-and-actions.md.

Bundle size

Features are separate packages and the interface features are opt-in, so unused features are not bundled. pnpm size reports gzip sizes against the specification budgets:

BuildBudgetCurrent
Engine only 50 KiB 35 KiB
Minimal editor 140 KiB 80 KiB
Standard editor 300 KiB 161 KiB
Document preset 450 KiB 391 KiB
Collaboration preset 400 KiB 228 KiB
Email preset 300 KiB 198 KiB
Full preset 600 KiB 455 KiB