The Rich Text Editor
Your Framework Deserves
Toolbar, bubble menu, tables, code blocks, image upload, Notion-style block menu, table of contents, and more. Import only what you need, your bundler tree-shakes the rest.
Angular, React, Vue, and Vanilla components included. Or use the headless core with any framework.
npm i @domternal/core Try it yourself
Get started in minutes
A few lines of code is all you need
import { Editor, Document, Text, Paragraph, Bold, Italic, Underline, } from '@domternal/core'; new Editor({ element: document.getElementById('editor')!, extensions: [Document, Text, Paragraph, Bold, Italic, Underline], content: '<p>Hello <strong>Bold</strong>, <em>Italic</em> and <u>Underline</u>!</p>', });
import { StarterKit, BubbleMenu } from '@domternal/core'; import { DomternalEditor, DomternalToolbar, DomternalBubbleMenu, } from '@domternal/vanilla'; import '@domternal/theme'; const editorEl = document.getElementById('editor')!; const toolbarEl = document.getElementById('toolbar')!; const bubbleEl = document.getElementById('bubble')!; const dm = new DomternalEditor(editorEl, { extensions: [StarterKit, BubbleMenu.configure({ element: bubbleEl })], content: '<p>Hello from Vanilla!</p>', }); new DomternalToolbar(toolbarEl, { editor: dm.editor }); new DomternalBubbleMenu(bubbleEl, { editor: dm.editor });
import { Component, signal } from '@angular/core'; import { DomternalEditorComponent, DomternalToolbarComponent, DomternalBubbleMenuComponent, } from '@domternal/angular'; import { Editor, StarterKit, BubbleMenu } from '@domternal/core'; @Component({ selector: 'app-editor', imports: [DomternalEditorComponent, DomternalToolbarComponent, DomternalBubbleMenuComponent], template: ` @if (editor(); as ed) { <domternal-toolbar [editor]="ed" /> } <domternal-editor [extensions]="extensions" [content]="content" (editorCreated)="editor.set($event)" /> @if (editor(); as ed) { <domternal-bubble-menu [editor]="ed" /> } ` }) export class EditorComponent { editor = signal<Editor | null>(null); extensions = [StarterKit, BubbleMenu]; content = '<p>Hello from Angular!</p>'; }
import { Domternal } from '@domternal/react'; import { StarterKit, BubbleMenu } from '@domternal/core'; export default function Editor() { return ( <Domternal extensions={[StarterKit, BubbleMenu]} content="<p>Hello from React!</p>" > <Domternal.Toolbar /> <Domternal.Content /> <Domternal.BubbleMenu /> </Domternal> ); }
<script setup> import { Domternal } from '@domternal/vue'; import { StarterKit, BubbleMenu } from '@domternal/core'; const extensions = [StarterKit, BubbleMenu]; </script> <template> <Domternal :extensions="extensions" content="<p>Hello from Vue!</p>" > <Domternal.Toolbar /> <Domternal.Content /> <Domternal.BubbleMenu /> </Domternal> </template>
Everything you need to build
rich editing experiences
A complete editor framework with full control over every aspect of your editor.
65+ Built-in Extensions
65+ extensions across 15 packages. Tables, images, emoji, mentions, details, syntax highlighting, Notion-style block menu, table of contents. Everything included.
Angular, React, Vue & Vanilla Wrappers
Ready-made components for Angular, React, Vue, and Vanilla: editor, toolbar, bubble menu, floating menu, emoji picker, notion color picker. Or use the headless core with any framework.
Built-in Toolbar & Theme
Every extension declares toolbar items via addToolbarItems(). 49 Phosphor icons included. Light & dark theme with CSS custom properties. Ready to customize.
Styled HTML Export
getHTML({ styled: true }) produces inline CSS ready for email clients, CMS, and Google Docs. Customizable styles for tables, blockquotes, code blocks, and more.
Markdown-Style Shortcuts
Type ## for heading, > for blockquote, - for list, **bold**, ==highlight==, --- for rule. Every extension registers its own input rules.
15,000+ Tests
4,000+ unit tests across all packages. 11,000+ Playwright E2E tests across 230+ specs and 4 demo apps. Every extension, mark, and node is tested.
Full table support,
any framework
- Cell merge & split (colspan/rowspan)
- 3 resize modes: neighbor, independent, redistribute
- constrainToContainer: lock or free table width
- Cell background, alignment, vertical align
- Export-ready: percent, pixel, or no column widths
- Floating cell toolbar on selection
- 18 table commands, 400+ tests
| Feature | Q1 | Q2 | Q3 |
|---|---|---|---|
| Editor Core | Released | Stable | Stable |
| Tables | Released | Stable | Stable |
| Theme | Light + Dark (Merged Cell) | ||
| Angular | 6 Components | Signals | OnPush |
| Vanilla | 6 Classes | EventTarget | SSR-safe |
Every extension you need
Batteries included: from basic formatting to advanced features.
65+ extensions across 15 packages. All MIT licensed.
View All Packages →Built for production
Architecture decisions that make the difference at scale.
Schema Conflict Detection
Duplicate extension names throw a clear error at startup. No mysterious production bugs from silent overwrites.
Extension Composability
create() → configure() → extend() with this.parent?.() to call the base version. Override any hook while preserving parent behavior. Fully typed.
Fluent Command API
editor.chain().focus().toggleBold().run() chains commands on a shared transaction. editor.can().toggleBold() dry-runs without side effects. Fully typed.
XSS-Hardened Images
Blocks javascript:, vbscript:, file: protocols across four layers: parseHTML, renderHTML, commands, and input rules.
Global Attribute Injection
addGlobalAttributes() lets extensions inject attributes into node types they don't own. TextAlign, TextColor, FontSize, Highlight, and UniqueID all use this pattern. Zero coupling.
Zero-Jitter Floating UI
All floating elements use position: absolute inside the editor with @floating-ui/dom. CSS compositor handles scroll. Zero JS during scroll events.
SSR Ready
Server-side rendering via linkedom. Generate HTML on the server without a browser. Works with Angular Universal, Astro, and any Node.js environment.
Framework-agnostic core, ready-made components
The headless core works with any framework. Angular, React, and Vue components ship today.
Simple, transparent pricing
Open source core, MIT licensed. Pro extensions coming soon for teams that need more.
- Complete editor engine
- Angular, React, Vue & Vanilla components (editor, toolbar, menus)
- Notion-style block menu, slash command & Table of Contents
- Full tables: merge, resize, styling
- 65+ extensions across 15 packages
- Built-in toolbar & theme (light + dark)
- Image upload, emoji picker & mentions
- Custom node views (React & Vue)
Everything in Open Source, plus:
- Real-time collaboration (Yjs/CRDT)
- Inline comments & threads
- Track changes & revision history
- PDF / Word / Markdown export
- AI writing assistant
- Priority support & SLA
- ··· And more planned