A rich text editor toolkit built on ProseMirror, with a headless core and first-class Angular, React, Vue, and Vanilla components. Take the core alone and drive the DOM yourself, add the toolbar and theme for a finished editor, or mount the components for your framework. Notion-style block editing, drag handle, slash menu and floating outline are included. JavaScript exports are tree-shakeable; the optional theme ships as one complete CSS stylesheet.
Website · Getting Started · Packages & Bundle Size
Live examples - full editors for Angular, React, Vue, and Vanilla, editable in the browser
- Headless core - use with any framework or vanilla JS/TS
- Angular components - editor, toolbar, bubble menu, floating menu, emoji picker, notion color picker (Angular 17.1+, signals, OnPush, zoneless-ready)
- React components - composable
Domternalcomponent, toolbar, bubble menu, floating menu, emoji picker, notion color picker, custom node views (React 18+) - Vue components - composable
Domternalcomponent,useEditor/useEditorStatecomposables, toolbar, bubble menu, floating menu, emoji picker, notion color picker, custom node views (Vue 3.3+) - Vanilla wrapper - framework-free class-based API for Astro, Svelte, Solid, plain HTML, and Web Components - editor, toolbar, bubble menu, floating menu, emoji picker, notion color picker
- Notion-style block UX - drag-to-reorder, block context menu, slash command, smart paste, keyboard reorder, floating Table of Contents, from
@domternal/extension-block-controlsand@domternal/extension-toc, withpreset: 'notion'for the layout and preset-aware behavior - Print to paper or PDF -
printDocument()leaves your app's chrome off the page, and the theme's paper layer applies to the reader's own Ctrl/Cmd+P with no code involved - 70+ extensions across core and 10 extension packages - nodes, marks, and behavior extensions
- 130+ chainable commands -
editor.chain().focus().toggleBold().run() - Full table support - cell merging, column resize, row/column controls, cell toolbar
- Tree-shakeable JavaScript - import only the JavaScript exports you use; the optional
@domternal/themedeliberately ships one complete stylesheet - ~59 KiB minified and gzipped (own code), ~140 KiB minified and gzipped total with runtime dependencies - see Packages for the full bundle breakdown
- TypeScript first - every package builds under
strict, withexactOptionalPropertyTypesandnoUncheckedIndexedAccess - 17,000+ automated test executions - unit coverage and a Playwright matrix across four demo apps
- Light and dark theme - 150+ CSS custom properties for full visual control
- Per-editor UI localization: replace labels at creation or runtime, keep English fallback text, and opt into complete German catalogs
- Inline styles export -
getHTML({ styled: true })produces inline CSS ready for email clients, CMS, and Google Docs - SSR helpers -
generateHTML,generateJSON,generateTextfor server-side rendering
pnpm add @domternal/coreimport { Editor, Document, Text, Paragraph, Bold, Italic, Underline } from '@domternal/core';
const editor = new Editor({
element: document.getElementById('editor')!,
extensions: [Document, Text, Paragraph, Bold, Italic, Underline],
content: '<p>Hello <strong>World</strong>!</p>',
});The example above wires the minimum schema by hand to show the headless model; in practice use StarterKit for a batteries-included setup with headings, lists, code blocks, history, and more.
Getting Started Guide - headless core, themed UI with toolbar, and Angular/React/Vue component setup
Every editor starts with English UI text and accepts its own i18n configuration. German
catalogs are available as optional /locales/de imports from core and each extension that
owns UI messages. Merge only the catalogs for the features you use:
import type { I18nOptions } from '@domternal/core';
import {
deMessages as coreDe,
deSearchAliases as coreAliasesDe,
} from '@domternal/core/locales/de';
import {
deMessages as tableDe,
deSearchAliases as tableAliasesDe,
} from '@domternal/extension-table/locales/de';
const german = {
locale: 'de',
messages: { ...coreDe, ...tableDe },
searchAliases: { ...coreAliasesDe, ...tableAliasesDe },
} satisfies I18nOptions;
editor.i18n.set(german);Missing messages fall back to English. Runtime language changes update Domternal's UI without translating or changing the document. Domternal does not add a language selector; your application chooses when to pass a new configuration. See the localization guide for wrapper examples, partial catalogs, formatting, and custom translation resolvers.
The 1.2.0 minor release adds per-editor UI localization, live language changes, and
optional German catalogs. Existing editor APIs and saved document formats remain
compatible. Upgrade installed @domternal/* packages together to 1.2.0: wrappers
require core >=1.2.0 <2.0.0, and extensions require both core and pm in that range.
See CHANGELOG.md for the release contents.
| Package | Description |
|---|---|
@domternal/core |
Editor engine with 13 nodes, 9 marks, 28 extensions, toolbar controller, and 52 built-in icons |
@domternal/theme |
Light and dark themes with 150+ CSS custom properties |
@domternal/angular |
Angular 17.1+ wrapper: 6 components (editor, toolbar, bubble menu, floating menu, emoji picker, notion color picker) |
@domternal/react |
React 18+ wrapper: composable component, toolbar, bubble menu, floating menu, emoji picker, notion color picker, node views |
@domternal/vue |
Vue 3.3+ wrapper: composable component, composables, toolbar, bubble menu, floating menu, emoji picker, notion color picker, node views |
@domternal/vanilla |
Framework-free class-based wrapper for Astro, Svelte, Solid, plain HTML, and Web Components |
@domternal/pm |
ProseMirror re-exports (state, view, model, transform, commands, keymap, history, tables, and more) |
@domternal/extension-block-controls |
Notion-style block UX: block handle, context menu, drag-to-reorder, keyboard reorder, slash command, floating menu, smart paste (formerly @domternal/extension-block-menu) |
@domternal/extension-toc |
Notion-style Table of Contents: floating outline, inline /toc block, scrollToHeading command |
@domternal/extension-table |
Tables with 18 commands: merge, split, resize, cell styling, row/column controls |
@domternal/extension-math |
LaTeX math: inline and block equations with a pluggable renderer (KaTeX) |
@domternal/extension-markdown |
GitHub-flavored Markdown import and export: markdown paste, insertMarkdown/setMarkdownContent, headless parser and serializer with fidelity warnings |
@domternal/extension-image |
Image with paste/drop upload, URL input, XSS protection, bubble menu |
@domternal/extension-emoji |
Emoji picker panel and :shortcode: autocomplete |
@domternal/extension-mention |
@mention autocomplete with multi-trigger and async support |
@domternal/extension-details |
Collapsible details/accordion blocks |
@domternal/extension-code-block-lowlight |
Syntax-highlighted code blocks powered by lowlight |
The table above lists all 17 current MIT packages. npm search may still show @domternal/extension-block-menu as a historical, deprecated 0.x entry. It is not an eighteenth current package. Briefly published 1.0.x builds were withdrawn from the registry; import @domternal/extension-block-controls directly.
See Packages & Bundle Size for a full breakdown of what each package includes and how tree-shaking works.
Domternal Pro adds the collaborative layer on top of these MIT packages, published as @domternal-pro/* on the public npm registry under a commercial license: real-time collaboration with live carets and presence, comments, version history, an AI assistant, columns, Word and PDF export, and a self-hosted collaboration server.
- Installation and licensing - install from npm, evaluate without a key, activate with a Commercial Key
- Pricing - plans and what each one includes
- Support and reporting issues - Pro defects are tracked in this repository through the Pro bug report template
Full documentation, live playgrounds, and API reference at domternal.dev.
- Getting Started - install and create your first editor
- Introduction - core concepts, architecture, and design decisions
- Packages & Bundle Size - what each package includes and bundle size breakdown
See CONTRIBUTING.md for commit conventions, PR guidelines, and development setup.
pnpm install # Install dependencies
pnpm build # Build all packages
pnpm test # Run tests
pnpm lint # Run linter
pnpm typecheck # Type checkRequires Node.js >= 22 and pnpm >= 10.
The source code is available under the MIT License. Use of the Domternal name and logo is governed by the Trademark Usage Policy.
