v6.0.0
Yoopta Editor v6.0.0
Release Date: February 23, 2026
This is a major release that transforms Yoopta into a fully headless, theme-ready editor with a new plugin architecture, real-time collaboration, and modern tooling.
Highlights
- Headless architecture — Plugins define structure and behavior only; UI is optional and provided by theme packages
- New UI layer (
@yoopta/ui) — Modular, composable UI components rendered as children of<YooptaEditor> - Theme system —
@yoopta/themes-shadcn(production-ready),@yoopta/themes-material(in progress),@yoopta/themes-base - Real-time collaboration — New
@yoopta/collaborationpackage powered by Yjs CRDT - Namespace APIs —
Blocks.*,Elements.*,Marks.*,Selection.*for structured editor operations - Element builder —
editor.y()API for programmatic content creation - New plugins — Steps, Tabs, Carousel, Emoji, Mention
- Email serializer —
editor.getEmail()for email-compatible HTML output - Turborepo + Yarn Berry — Modern monorepo tooling with build caching and selective dev mode
Breaking Changes
Editor creation
Plugins and marks are now passed to createYooptaEditor() instead of the <YooptaEditor> component:
// Before (v4/v5)
<YooptaEditor plugins={plugins} marks={marks} value={value} onChange={onChange} />
// After (v6)
const editor = useMemo(() => createYooptaEditor({ plugins, marks }), []);
<YooptaEditor editor={editor}>
<YooptaToolbar />
<YooptaSlashCommandMenu />
{/* ... */}
</YooptaEditor>Content management
The value/onChange controlled pattern on the component is removed:
// Set content
editor.setEditorValue(value);
// Listen to changes
editor.on('change', (value) => { ... });
// Or use onChange prop on <YooptaEditor>
<YooptaEditor editor={editor} onChange={(value, { operations }) => { ... }} />UI components
@yoopta/tools is deprecated. Migrate to @yoopta/ui:
import {
YooptaToolbar,
YooptaActionMenuList,
YooptaSlashCommandMenu,
YooptaFloatingBlockActions,
SelectionBox,
} from '@yoopta/ui';All UI elements are now children of <YooptaEditor> and use useYooptaEditor() internally.
New Features
Headless plugin architecture
Plugins are now purely structural — they define block types, elements, behavior, and parsers without shipping any visual UI. Theme packages provide optional styled renderers:
// Apply theme to all plugins
import { applyTheme } from '@yoopta/themes-shadcn';
const plugins = applyTheme([Paragraph, Callout, Headings.HeadingOne, ...]);
// Or apply to individual plugins
import { CalloutUI } from '@yoopta/themes-shadcn/callout';
const CalloutWithUI = Callout.extend({ elements: CalloutUI });Namespace APIs
Structured APIs for all editor operations:
import { Blocks, Elements, Marks, Selection } from '@yoopta/editor';
Blocks.insertBlock(editor, { ... });
Blocks.deleteBlock(editor, { ... });
Blocks.toggleBlock(editor, { ... });
Blocks.moveBlock(editor, { ... });
Blocks.duplicateBlock(editor, { ... });
Blocks.splitBlock(editor, { ... });
Blocks.mergeBlock(editor, { ... });
Blocks.increaseBlockDepth(editor, { ... });
Blocks.decreaseBlockDepth(editor, { ... });
Elements.insertElement(editor, { ... });
Elements.updateElement(editor, { ... });
Elements.deleteElement(editor, { ... });
Elements.getElement(editor, { ... });
Marks.update(editor, { type: 'highlight', value: { color: 'red' }, at: [0, 1, 2] });Element builder (editor.y)
Programmatic content creation:
// Create block element
editor.y('paragraph', { props: {...}, children: [...] });
// Create text node with marks
editor.y.text('Hello', { bold: true, italic: true });
// Create inline element
editor.y.inline('link', { props: { url: '...' }, children: [...] });Event system
editor.on('change', (value) => { ... });
editor.on('focus', () => { ... });
editor.on('blur', () => { ... });
editor.on('block:copy', (data) => { ... });
editor.on('path-change', (paths) => { ... });
editor.once('change', handler);
editor.off('change', handler);ElementOptions (@yoopta/ui)
Compound component for inline element configuration popovers, built on Radix UI:
<ElementOptions.Root blockId={blockId} element={element}>
<ElementOptions.Trigger />
<ElementOptions.Content>
<ElementOptions.Group label="Settings">
<ElementOptions.Select options={options} />
<ElementOptions.Toggle />
<ElementOptions.Slider />
<ElementOptions.ColorPicker />
<ElementOptions.Input />
</ElementOptions.Group>
</ElementOptions.Content>
</ElementOptions.Root>Hooks: useElementOptions() and useUpdateElementProps<T>().
Real-time collaboration (@yoopta/collaboration)
New core package for collaborative editing:
- Technology: Yjs CRDT for conflict-free sync with Slate-Yjs binding
- Features: Awareness, remote cursors, selection tracking
- Infrastructure: WebSocket provider support
- Hooks:
useCollaboration,useConnectionStatus,useRemoteCursors
import { useCollaboration } from '@yoopta/collaboration';Email serializer
const emailHTML = editor.getEmail(content, {
head: { title: 'My Email' },
body: { attrs: { style: { width: '600px' } } },
customTemplate: (content) => `<html>...${content}...</html>`,
});All 23 plugins include email parsers with table-based layouts for email client compatibility.
New plugins
- Steps — Numbered step-by-step lists with heading and content per step
- Tabs — Tabbed content containers (renders as sections in email)
- Carousel — Horizontally scrollable content cards
- Emoji — Emoji insertion with dropdown picker
- Mention — @mention with dropdown, avatar support, floating position, extend render
Table plugin enhancements
scrollableprop (default:true) — tables respect column widths and scroll horizontally- Column resize handles with portal rendering
- Improved column/row controls positioning in scrollable tables
JSON clipboard support
Copy/paste preserves Yoopta block structure via JSON clipboard data.
Bug Fixes
Editor core
- Block focus on click — Fixed brief focus jump to the first block when clicking other blocks
- SelectionBox scroll — Auto-scrolling when dragging selections near viewport edges; selection origin tracks document coordinates
- SelectionBox — Eliminated native text selection during programmatic block selection
Lists
- Enter key — Fixed focus loss when pressing Enter in bulleted, numbered, and todo lists (cursor became invisible, especially in Safari)
Image
- Inline toolbar after upload — Fixed toolbar not appearing after file upload (file picker dialog cleared Slate selection)
- Left-side resize — Fixed left handle resizing with proper position anchoring
- Resize handlers — Added white ring styling for visibility on dark images
- Preview blob leak — Fixed stale closure in
useImagePreviewwhereclearPreview()failed to revoke blob URLs - Upload validation — Enhanced hooks with validation for upload and delete options
Video
- Preview blob leak — Fixed same stale closure issue as image plugin in
useVideoPreview
FloatingBlockActions
- Hover detection — Improved reach detection using JavaScript-based extended bounds instead of CSS pseudo-elements
- Margin offset — Fixed positioning when blocks have margin-top styles
FloatingToolbar
- Safari — Fixed immediate toolbar closure on button clicks (
preventDefaulton mouseDown) - Safari inline toolbars — Fixed incorrect (0,0) positioning using
useLayoutEffectandisReadystate
HighlightColorPicker
- Click-outside handling — Fixed using FloatingOverlay for cross-browser reliability
- History flooding — Added 300ms debounce to onChange to prevent excessive undo/redo entries
Steps plugin
- moveUp/moveDown — Fixed buggy methods using proper
Transforms.moveNodes
Code/CodeGroup
- Theme isolation — Shiki theme colors now use scoped CSS variables on elements instead of global document variables
Infrastructure
Turborepo + Yarn Berry migration
- From: Lerna + Yarn v1
- To: Turborepo + Yarn Berry (v4)
workspace:*protocol resolves local packages correctly- Build caching and filtering for selective dev mode
- Eliminated
packages/development/—web/next-app-example/is now the dev workspace
New commands
yarn dev # Start dev server
yarn dev --filter=@yoopta/editor # Dev + watch one package
yarn dev --filter=@yoopta/editor --filter=@yoopta/paragraph # Watch multiple
yarn build --filter=@yoopta/editor # Build single packagePublishing
Versioning uses Changesets with fixed version groups — all @yoopta/* packages share the same version.
React 19
Monorepo upgraded to React 19 while maintaining backward compatibility via peerDependencies: "react": ">=18.2.0".
Migration Guide
1. Update packages
npm install @yoopta/editor@^6.0.0 @yoopta/ui@^6.0.0
# Install theme if desired
npm install @yoopta/themes-shadcn@^6.0.02. Update editor creation
// Old
const editor = useMemo(() => createYooptaEditor(), []);
<YooptaEditor editor={editor} plugins={plugins} marks={marks} value={value} onChange={onChange} />
// New
const editor = useMemo(() => createYooptaEditor({ plugins, marks, value: initialValue }), []);
<YooptaEditor editor={editor} onChange={(value, { operations }) => { ... }}>
{/* UI components as children */}
</YooptaEditor>3. Replace @yoopta/tools with @yoopta/ui
import {
YooptaToolbar,
YooptaActionMenuList,
YooptaSlashCommandMenu,
YooptaFloatingBlockActions,
} from '@yoopta/ui';4. Apply theme (optional)
import { applyTheme } from '@yoopta/themes-shadcn';
const plugins = applyTheme([Paragraph, Callout, ...]);5. Content handling
// Set value
editor.setEditorValue(savedContent);
// Get value
const content = editor.getEditorValue();Package Versions
All @yoopta/* packages are published at version 6.0.0:
| Package | Description |
|---|---|
@yoopta/editor |
Core editor engine |
@yoopta/ui |
UI components (toolbar, menus, block actions, element options, selection box) |
@yoopta/collaboration |
Real-time collaboration (Yjs) |
@yoopta/exports |
HTML/Markdown/PlainText/Email serializers |
@yoopta/marks |
Text formatting (Bold, Italic, Underline, Strike, Code, Highlight) |
@yoopta/themes-shadcn |
Shadcn UI theme |
@yoopta/themes-material |
Material Design theme (in progress) |
@yoopta/themes-base |
Base theme |
@yoopta/paragraph |
Paragraph plugin |
@yoopta/headings |
HeadingOne, HeadingTwo, HeadingThree |
@yoopta/lists |
BulletedList, NumberedList, TodoList |
@yoopta/blockquote |
Blockquote plugin |
@yoopta/callout |
Callout plugin |
@yoopta/code |
Code block plugin |
@yoopta/image |
Image plugin |
@yoopta/video |
Video plugin |
@yoopta/embed |
Embed plugin |
@yoopta/file |
File plugin |
@yoopta/link |
Link plugin |
@yoopta/divider |
Divider plugin |
@yoopta/table |
Table plugin |
@yoopta/accordion |
Accordion plugin |
@yoopta/mention |
Mention plugin |
@yoopta/emoji |
Emoji plugin |
@yoopta/steps |
Steps plugin |
@yoopta/tabs |
Tabs plugin |
@yoopta/carousel |
Carousel plugin |
@yoopta/table-of-contents |
Table of Contents plugin |