Releases
Changelog
Version history for @parityfox/rune-editor — what changed in each release.
All notable changes to Rune are documented here.
This project adheres to Semantic Versioning. Dates follow YYYY-MM-DD.
[1.2.0] — 2026-06-15
✨ Added
- Inline emoji picker — a toolbar
🙂button opens a categorized picker and inserts the chosen emoji inline at the caret (headings, paragraphs, lists, callout bodies). Complements the existing:shortcode:autocomplete. Enable viaplugins.emojiand place with theemojitoolbar item.
🐛 Fixed
- Inserting a callout from the
/menu no longer drops the caret into a paragraph below the (empty) callout — the Enter that picked the item was leaking into the callout's own Enter handler and exiting it - Selecting a
:shortcode:emoji inside a callout body no longer appends a stray blank line
🔒 Security
- Bumped
esbuildto0.28.1, clearing GHSA-gv7w-rqvm-qjhr (high) and GHSA-g7r4-m6w7-qqqr (low).esbuildis a devDependency used only bybuild:demoand is not shipped, so published-package consumers were never affected
📝 Docs
- Documented the Emoji & Icons feature and added
emojito the example config - Pointed the Live Playground links at
https://runeditor.com
[1.1.1] — 2026-06-10
📝 Docs
- Fixed the no-bundler / CDN install instructions: use the full scoped, version-pinned package name (
@parityfox/rune-editor@1.1.1) instead of the unscopedrune-editor, which is a different (unregistered) package and an unsafe thing to load from a CDN - Documented the dedicated Vue (
/vue) and Svelte (/svelte) adapters, replacing the stale "no dedicated adapter" hand-wiring - Completed the subpath exports table (
vue,svelte,collab,server) - Corrected the Node requirement to ≥ 18 and the adapter snippets to use the exported
StarterKit
[1.1.0] — 2026-06-10
A big feature release: real-time collaboration, two-way Markdown, a portable JSON model, new container blocks, framework adapters, and a broad sweep of accessibility, performance, and correctness work.
✨ Added
Collaboration
- Real-time collaboration graduated to a first-class, exported feature (Yjs-backed)
- Presence: roster API, avatars, idle/away states, and follow-mode
- Suggestion mode — track-changes-style edits tagged as local, rendered per-block
- Hardened collab server: room-name validation, room-count caps, rate limiting, and send backpressure
Content model & Markdown
- Portable JSON document model —
getJSON()/setJSON()plus server-side render - Two-way Markdown —
setMarkdown(),insertMarkdown(), and paste-as-Markdown - Paste converts Markdown even when the clipboard also carries rich HTML
- Nested blockquotes in Markdown conversion
Blocks, marks & input
- Container blocks: Toggle (collapsible) and Columns
Highlightmark- InputRule / PasteRule engine, with
SmartTypographyandInlineMarkdownextensions - Suggestion primitive for trigger characters (
@/#/:) - Non-destructive decoration / overlay layer (FindReplace highlights now ride on it)
- Video embeds are drag-to-resize (width, height, and diagonal)
- Links use an inline popover for add/edit and are clickable (⌘/Ctrl-click to open)
- Tables gain a size picker on insert and visible add/remove controls
toggleMarkcommand and element-mark support inisActive
Extensibility & adapters
- Extension registry with manifests and runtime
use() - Vue 3 and Svelte adapters
- Hand-authored TypeScript declarations
- Config-driven playground + GitHub Pages deploy
♿ Accessibility
- Live region announcing key actions to assistive tech
- Accessible name and AT-visible placeholder on the editable region
- Roving tabindex + arrow-key navigation in the toolbar;
aria-pressedon toggles - Slash menu exposes the active option via
aria-activedescendant - Keyboard-operable task checkboxes and callout emoji icons; controls activate on click
- Focus-managed toolbar/bubble popups
- Honor
prefers-reduced-motion; muted-text contrast raised to WCAG AA
⚡ Performance
- rAF-coalesced presence/comments overlay rendering, selectionchange emits, and toolbar active-state recompute
- rAF-throttled DragReorder with touch/pen (Pointer Events) support
- Dropped the redundant document clone in
getHtml()
🐛 Fixed
- Enter inside a callout no longer splits the flex layout / jumps the caret
- Bold/Italic/etc. no longer show active inside headings
- FindReplace: Replace advances to the next match and won't re-match replacements; re-highlight debounced
- Caret position restored on undo/redo
- Deleting a table's header row promotes the first body row to header
- Line breaks preserved when toggling code blocks
- Indent/outdent/text-align apply to the editable leaf, not the container
- Markdown shortcuts guarded to the block-end caret position
- FormatPainter no longer merges blocks or churns the DOM, and reproduces super/subscript
onChangeno longer fires during editor construction- Markdown export: longer backtick fences, escaped brackets, preserved relative URLs, nested lists and task inline marks
- EventBus isolates subscribers so one throwing handler can't break others
- Lifecycle cleanup: collab bindings, FormatPainter, and SlashMenu all tear down on
destroy() - Fixed P0/P1 code-review issues across undo, onChange, lifecycle, SSR, and the collab server
🔒 Security
- Broadened history-snapshot data-URI stripping to
hrefandsrcset
📚 Docs & packaging
- CI and release GitHub Actions workflows
engines.nodedeclared;react/react-dommarked as optional peer dependencies- README fixes: Next.js/SSR client-only usage, React quick-start extensions, collab and config examples
[1.0.1] — 2026-02-23
🔧 Changed
- Ship the logo in the published package and serve the README logo via jsDelivr
[1.0.0] — 2026-02-23
First public release. 🎉
✨ Added
Core Engine
Editorclass with full public API (getHtml,setHtml,getText,getMarkdown,print,focus,blur,enable,disable,destroy,isEmpty)Schema— extension registry with block, mark, and plugin type support; toolbar item cachingCommands— command registry with chainable API (editor.chain().toggleBold().toggleItalic().run())EventBus— pub/sub event system (change,selectionchange,keydown,paste,slash:open,slash:close)History— undo/redo stack with configurable depthSelection— caret/selection helpers (getBlock,setAtStart,setAtEnd,isCollapsed)
Block Extensions
Paragraph— default block, auto-wraps bare textHeading— H1, H2, H3 with slash commands and markdown shortcutsBulletList/OrderedList— nested lists, tab to indentBlockquote—>markdown shortcutCodeBlock— fenced`shortcut, monospace displayHorizontalRule—---markdown shortcutCallout— Notion-style coloured callout box with emoji supportTaskList— interactive checklist with click-to-toggle checkboxesVideoEmbed— YouTube/Vimeo URL → iframe embedImage— file picker + base64 preview + asyncuploadImagehook for hosted URLsTable— full table with keyboard navigation (Tab/Shift+Tab), row/column add/delete
Mark Extensions
Bold,Italic,Underline,Strike— standard inline marks with keyboard shortcutsCode— inline<code>with ``` markdown shortcutLink—<a>with dangerous-protocol validationSuperscript,SubscriptFontSize— em presets + custom px inputFontFamily— preset font stack pickerTextColor,TextBackground— colour palettes with live indicator swatch
Formatting Extensions
TextAlign— left / center / right / justify per blockLineHeight— 1.0 → 2.0 pickerIndent,Outdent— list and block indentation
Plugin Extensions
MarkdownShortcuts— converts Markdown syntax on input (block and inline)FindReplace—⌘Ffloating panel with match count, prev/next navigation, replace allDragReorder— drag handle in left gutter to reorder any block (pointer-event based)FormatPainter— copy formatting from one selection and paint it onto another
UI
Toolbar— configurable item list; button, dropdown, and panel types; body-appended panels (never clipped)BubbleMenu— appears on text selection; hides when format painter is activeSlashMenu— Notion-style/command palette with search filtering- Tooltips on toolbar hover
- Dark mode via
data-theme="dark"CSS custom properties
Export
editor.getMarkdown()— HTML → Markdown converter (htmlToMarkdown) handling all block and inline typeseditor.print()— clean print view stripping all editor UI chrome
Adapters
- React —
useRunehook +RuneEditorcomponent - Web Component —
<rune-editor>custom element withcontent,placeholder,readonlyattributes; fireschangeCustomEvent; exposesgetHtml,setHtml,getMarkdown,print,cmd
Developer Experience
rune.config.js— single file to enable/disable all features; changes propagate automaticallycreateFromConfig(target, config, overrides)— factory function for config-driven setup
🔒 Security
sanitize()strips all non-allowlisted attributes from pasted HTML- Dangerous URL protocols (
javascript:,vbscript:,data:text/html) blocked inhref,src, andstyle - Whitespace and null-byte stripping to prevent protocol-bypass on URL checks
For upcoming features and known issues, see TODO.md.