A set of ready-to-use rich text editors created with a powerful framework, with real-time collaborative editing in mind.
npx @tessl/cli install tessl/npm-ckeditor5@46.0.0CKEditor 5 is a modern JavaScript rich-text editor framework written in TypeScript with MVC architecture, custom data model, and virtual DOM. It provides comprehensive WYSIWYG editing solutions with extensive collaboration support, including real-time collaborative editing, comments, and tracking changes. The framework offers a modular plugin system supporting diverse editing features from basic text formatting to advanced capabilities like tables, media embedding, markdown support, and export functionality.
npm install ckeditor5import { ClassicEditor, InlineEditor, BalloonEditor, DecoupledEditor } from 'ckeditor5';For ES modules:
import { ClassicEditor } from 'ckeditor5';For CommonJS:
const { ClassicEditor } = require('ckeditor5');import { ClassicEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5';
ClassicEditor
.create(document.querySelector('#editor'), {
plugins: [Essentials, Paragraph, Bold, Italic],
toolbar: ['bold', 'italic']
})
.then(editor => {
console.log('Editor was initialized', editor);
})
.catch(error => {
console.error(error);
});CKEditor 5 is built around several key architectural components:
Ready-to-use editor implementations with different UI approaches and integration patterns.
class ClassicEditor extends Editor {
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<ClassicEditor>;
}
class InlineEditor extends Editor {
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<InlineEditor>;
}
class BalloonEditor extends Editor {
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<BalloonEditor>;
}
class DecoupledEditor extends Editor {
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<DecoupledEditor>;
}
class MultiRootEditor extends Editor {
static create(
sourceElementsOrData: Record<string, HTMLElement | string>,
config?: EditorConfig
): Promise<MultiRootEditor>;
}Foundation classes for building and extending CKEditor 5, including the plugin system, command pattern, and configuration management.
abstract class Editor {
readonly model: Model;
readonly editing: EditingController;
readonly data: DataController;
readonly ui: EditorUI;
readonly keystrokes: EditingKeystrokeHandler;
readonly commands: CommandCollection;
readonly plugins: PluginCollection;
readonly config: Config;
setData(data: string): void;
getData(options?: { rootName?: string; trim?: 'empty' | 'none' }): string;
destroy(): Promise<unknown>;
execute(commandName: string, ...args: any[]): any;
}
abstract class Plugin {
readonly editor: Editor;
static readonly pluginName?: string;
static readonly requires?: PluginConstructor[];
static readonly isOfficialPlugin?: boolean;
constructor(editor: Editor);
init?(): void | Promise<void>;
afterInit?(): void | Promise<void>;
destroy?(): void | Promise<void>;
}
abstract class Command {
readonly editor: Editor;
value: unknown;
isEnabled: boolean;
constructor(editor: Editor);
abstract execute(...args: any[]): void;
refresh(): void;
destroy(): void;
}Low-level editing engine with model-view architecture, operations system, and conversion pipeline for advanced customization and plugin development.
class Model {
readonly document: ModelDocument;
readonly schema: ModelSchema;
readonly markers: MarkerCollection;
change<TReturn>(callback: (writer: ModelWriter) => TReturn): TReturn;
enqueueChange<TReturn>(callback: (writer: ModelWriter) => TReturn): TReturn;
insertContent(content: ModelDocumentFragment | ModelItem, selectable?: Selectable): void;
getSelectedContent(selection: ModelSelection): ModelDocumentFragment;
deleteContent(selection: ModelSelection, options?: object): void;
}
class EditingController {
readonly model: Model;
readonly view: EditingView;
readonly mapper: Mapper;
readonly downcastDispatcher: DowncastDispatcher;
readonly upcastDispatcher: UpcastDispatcher;
convertView(): void;
destroy(): void;
}
class DataController {
readonly model: Model;
readonly processor: DataProcessor;
readonly upcastDispatcher: UpcastDispatcher;
readonly downcastDispatcher: DowncastDispatcher;
init(data: string): void;
set(data: string, options?: object): void;
get(options?: object): string;
toModel(viewElementOrFragment: ViewElement | ViewDocumentFragment): ModelDocumentFragment;
toView(modelElementOrFragment: ModelElement | ModelDocumentFragment): ViewDocumentFragment;
}Rich text editing features including text formatting, lists, tables, images, links, and specialized content types.
// Text Formatting
class Bold extends Plugin {
static readonly pluginName: 'Bold';
static readonly requires: [BoldEditing, BoldUI];
}
class Italic extends Plugin {
static readonly pluginName: 'Italic';
static readonly requires: [ItalicEditing, ItalicUI];
}
// Lists
class List extends Plugin {
static readonly pluginName: 'List';
static readonly requires: [ListEditing, ListUI];
}
// Tables
class Table extends Plugin {
static readonly pluginName: 'Table';
static readonly requires: [TableEditing, TableUI];
}
// Images
class Image extends Plugin {
static readonly pluginName: 'Image';
static readonly requires: [ImageEditing, ImageUI];
}
// Links
class Link extends Plugin {
static readonly pluginName: 'Link';
static readonly requires: [LinkEditing, LinkUI];
}Complete UI framework with components, views, and utilities for building rich editor interfaces and custom UI elements.
abstract class View {
readonly locale?: Locale;
element?: HTMLElement;
template?: Template;
isRendered: boolean;
render(): void;
destroy(): void;
setTemplate(definition: TemplateDefinition): void;
}
class ButtonView extends View {
label?: string;
icon?: string;
tooltip?: string;
isEnabled: boolean;
isVisible: boolean;
isToggleable: boolean;
isOn: boolean;
class?: string;
type: 'button' | 'submit' | 'reset';
execute(): void;
}
class ToolbarView extends View {
readonly items: ViewCollection;
readonly focusTracker: FocusTracker;
readonly keystrokes: KeystrokeHandler;
options: ToolbarOptions;
focus(): void;
focusLast(): void;
}
class DropdownView extends View {
readonly buttonView: ButtonView;
readonly panelView: DropdownPanelView;
isOpen: boolean;
open(): void;
close(): void;
}Essential utilities for working with CKEditor 5, including collections, observables, DOM helpers, and development tools.
class Collection<T> {
readonly length: number;
add(item: T, index?: number): void;
addMany(items: Iterable<T>, index?: number): void;
get(idOrIndex: string | number): T | null;
has(itemOrId: T | string): boolean;
getIndex(itemOrId: T | string): number;
remove(subject: T | number | string): T;
clear(): void;
map<U>(callback: (item: T, index: number) => U, thisArg?: any): U[];
find(callback: (item: T, index: number) => boolean, thisArg?: any): T | undefined;
filter(callback: (item: T, index: number) => boolean, thisArg?: any): T[];
}
class Config {
get(name: string): unknown;
set(name: string | object, value?: unknown): void;
define(name: string | object, value?: unknown): void;
names(): IterableIterator<string>;
}
class Locale {
readonly language: string;
readonly contentLanguage: string;
readonly uiLanguageDirection: 'ltr' | 'rtl';
readonly contentLanguageDirection: 'ltr' | 'rtl';
t(message: string, values?: string[]): string;
}interface EditorConfig {
toolbar?: ToolbarConfig;
plugins?: PluginConstructor[];
language?: LanguageConfig;
ui?: UiConfig;
initialData?: string;
placeholder?: string;
removePlugins?: string[];
extraPlugins?: PluginConstructor[];
substitutePlugins?: PluginConstructor[];
[pluginName: string]: any;
}
interface ToolbarConfig {
items?: ToolbarConfigItem[];
removeItems?: string[];
shouldNotGroupWhenFull?: boolean;
viewportTopOffset?: number;
}
type ToolbarConfigItem = string | {
label?: string;
icon?: string;
items?: ToolbarConfigItem[];
tooltip?: string;
withText?: boolean;
};
interface LanguageConfig {
ui?: string;
content?: string;
}
interface UiConfig {
viewportOffset?: ViewportOffsetConfig;
poweredBy?: PoweredByConfig;
}