Nightly releases changelog
Below you can find the changelog for the latest CKEditor 5 nightly release (0.0.0-nightly-20260917.0).
These entries are generated automatically based on the files stored in the .changelog/ directory. As a result, some items may be unclear or difficult to interpret. We apologize for any inconvenience.
The changelog is built starting from the latest stable release (48.5.1), using it as a reference point for collecting changes.
To learn more about CKEditor 5 nightly releases, see #14502.
0.0.0-nightly-20260917.0 (September 18, 2026)
MAJOR BREAKING CHANGES ℹ️
ckeditor5, core, utils: The
@ckeditor/ckeditor5-watchdogpackage was removed, and with it the automatic restart of a crashed editor. An editor that crashes now stays as it is, with its content and its undo history, instead of being rebuilt from the data it had before.- The
EditorWatchdogandContextWatchdogclasses are gone, as are theWatchdogbase class and theWatchdogConfigtype. They are no longer re-exported fromckeditor5. - The
Editor.EditorWatchdogandEditor.ContextWatchdogstatic fields were removed from every editor class. ActionsRecorderis not affected. It only lived in that package and now ships from@ckeditor/ckeditor5-core.
Use
onEditorError()to observe errors instead. It reports the error together with the editor or context it came from, and returns a function that unregisters the callback. Where the editor class is all you have — a framework integration, above all — the same function is reachable asEditor.onEditorError()andContext.onEditorError().import { onEditorError } from 'ckeditor5'; const off = onEditorError( ( { error, source } ) => { console.error( 'An error escaped', source, error ); } );If you used
ContextWatchdogto share a context between editors, create theContextyourself and pass it in the editor configuration. The context is then yours to destroy when you are done with it, whichContextWatchdogused to do for you.const context = await Context.create( contextConfig ); const editor = await ClassicEditor.create( { context, /* ... */ } );Integrators who relied on the restart should handle the reported errors themselves — reload the editor, tell the user, or report to their error tracker.
- The
ckeditor5, ui: The UI theme is now built on a three-layer system of CSS custom properties, replacing the previous flat set of theme variables with more granular, predictable customization points. Closes #19910.
The layers are:
- Foundation primitives, such as the spacing, radius, and color scales.
- Semantic design roles shared across components, such as control padding and surface radius.
- Per-component override points, such as the button or dialog tokens.
Custom themes that read the previous variables keep working, as the legacy names are preserved as backward-compatible aliases. The breaking surface is narrower: some legacy hooks were removed outright, and overriding a foundation or legacy variable no longer necessarily cascades through the semantic and component layers, so scoped overrides should target the component token closest to the property. See the theme token naming guide in the CKEditor 5 documentation for the layer model and the recommended override points.
ckeditor5, ui: The editor now ships a refreshed, more modern default look, expressed entirely through the new tiered design tokens. Every integration that uses the default theme gets the new appearance. Closes #20235.
The previous look remains available as an opt-in legacy theme - a single stylesheet you load - so integrations that prefer the old appearance can keep it with a one-line change.
Some of the refreshed styles also apply to
.ck-content, so already-published documents render slightly differently - for example comment and suggestion markers, block quotes, code blocks, and horizontal lines. Rollback snippets that restore the previous content colors ship with this release.Custom themes are largely unaffected: CSS that reads the previous token names keeps working through backward-compatible aliases. Overriding a legacy name to re-skin the editor's internals is the part that changes - use the new tokens or the legacy theme instead. See the theme migration guide for the upgrade path.
core:
ActionsRecordermoved from@ckeditor/ckeditor5-watchdogto@ckeditor/ckeditor5-core. It was never part of the Watchdog — it only lived in that package — and the package is removed in this release.Nothing changes for anyone importing from
ckeditor5, which re-exports@ckeditor/ckeditor5-core. Code importing from the Watchdog package directly has to change:// Before. import { ActionsRecorder } from '@ckeditor/ckeditor5-watchdog'; // After. import { ActionsRecorder } from '@ckeditor/ckeditor5-core';The
ActionsRecorderConfig,ActionsRecorderEntry,ActionsRecorderEntryEditorSnapshot,ActionsRecorderErrorCallback,ActionsRecorderFilterCallbackandActionsRecorderMaxEntriesCallbacktypes moved with it, as did theconfig.actionsRecorderdeclaration, so the configuration option keeps its typing.ui: The
TooltipManagerlifecycle has changed. It is no longer instantiated per editor withnew TooltipManager( editor ), and its constructor is now private: obtain the shared instance through the new staticTooltipManager.for( locale )method, which reference counts its holders, and callrelease()on it, instead ofdestroy( editor ), once a holder no longer needs it. As before, there is a single shared instance per page, soeditor.ui.tooltipManageris the same object for every editor, and theLocaleof the first caller is the one it uses. See #3891.ui: The
BodyCollection#detachFromDom()method has been renamed toBodyCollection#destroy(). Its behavior is unchanged: it destroys the collection's views and removes their container from the DOM. The new name makes clear that this is a permanent teardown, distinct from the new and reversibleBodyCollection#unmountFromDom()method. Replace everydetachFromDom()call withdestroy(). See #3891.All packages and CDN builds now target ES2023, up from ES2022.
The distributed stylesheets now use native CSS nesting instead of flattened selectors. Tools that post-process the CKEditor 5 CSS must support nesting. Some PostCSS configurations and minifiers are older than CSS nesting. If your build uses one, add a nesting transform to it.
MINOR BREAKING CHANGES ℹ️
block-quote, code-block: Block quotes and code blocks now use lighter border and background colors. As these are content styles, the change also affects already-published content. To restore the previous colors, add this CSS after the editor content styles: See #19910.
.ck-content blockquote { border-left: solid 5px hsl(0, 0%, 80%); } .ck-content[dir="rtl"] blockquote { border-right: solid 5px hsl(0, 0%, 80%); } .ck-content pre { background: hsla(0, 0%, 78%, 0.3); border: 1px solid hsl(0, 0%, 77%); }export-pdf, export-word: The
converterOptions.extra_http_headersoption no longer accepts an object keyed by the domain. Pass an array of{ domain, headers }entries instead.// Before. converterOptions: { extra_http_headers: { 'https://medias.example.org/': { authorization: 'Bearer xxx' } } } // After. converterOptions: { extra_http_headers: [ { domain: 'https://medias.example.org/', headers: { authorization: 'Bearer xxx' } } ] }The object form never worked in the editor configuration, because configuration keys are split on every
.character, so this affects only integrations passing the converter options directly to theexportPdforexportWordcommand.comments, track-changes: The default colors of comment highlights and suggestion insertion/deletion markers in the editing content have been refreshed to align with the new editor theme. Because these styles also apply to published
.ck-content, existing documents render with the new colors. To restore the previous appearance, override the--ck-comment-marker-*and--ck-suggestion-marker-*custom properties (see the content styles rollback snippet).fullscreen, ui: Every editor stylesheet now declares its CSS variables on both
:rootand:host, so overriding a variable on:rootno longer affects an editor inside a shadow root. Override it on the shadow host element instead, and declare the variables of a custom stylesheet on both selectors. See the "Styles inside a shadow DOM" section of the CSS guide. See #3891.The few rules that have to reach the light DOM are no longer shipped in the theme stylesheets. They are technical classes such as
ck-fullscreen-scroll-locked, which locks the page scroll, and they are adopted into the document at runtime instead, so overriding one of them may need higher specificity than before.engine: The
ViewRenderer#domDocumentsproperty has been removed. A set of documents can no longer describe where an editor renders, because an editing root may live in a shadow root instead. The renderer tracks the editing root elements themselves now, in a private property, and there is no public replacement. See #3891.fullscreen: The default container of the fullscreen mode has changed. When
config.fullscreen.containeris not set, the fullscreen mode is mounted in the sharedconfig.ui.overlayContainer, if there is one, and otherwise in the shadow root the editor lives in. It falls back to the<body>element, which used to be the only default, when there is neither. An explicitly configured container is still honored. See #3891.The option is also no longer given a default value internally, so
editor.config.get( 'fullscreen.container' )returnsundefinedinstead of the<body>element when the integrator did not set it.Custom CSS may need updating: the wrapper of a fullscreen mode that fills an integrator-provided container is marked with the
ck-fullscreen__main-wrapper_custom-containerclass now.horizontal-line: Horizontal lines now use a lighter background color. As this is a content style, the change also affects already-published content. To restore the previous color, add this CSS after the editor content styles: See #19910.
.ck-content hr { background: hsl(0, 0%, 87%); }ui: The editor's body collection (floating user interface such as balloons, dialogs, and tooltips) is no longer attached to the DOM during editor creation. It is attached once the editor's editing root is connected to the document, and
.ck-body-wrapperis no longer a single shared element: there is one wrapper per mount target, so an editor in a shadow root or with a configuredconfig.ui.overlayContainergets a wrapper of its own. See #3891.For an editor created on a detached element,
.ck-body-wrapperis therefore not present in the DOM immediately afterEditor.create()resolves. Code that located it that way, for example throughdocument.querySelector( '.ck-body-wrapper' ), should useeditor.ui.view.body.bodyCollectionContainerinstead. That element is created on demand and is available even before the collection is attached to the DOM.ui: The
clickOutsideHandler()utility function no longer accepts thelistenerOptionsoption, so the priority and the capture mode of its listener can no longer be configured. Remove the option from the call. The function needs those settings for itself: to detect a click inside a context element that lives in a shadow root, it combines its listener on the document with listeners on the shadow roots of the context elements it is given. See #3891.uploadcare: To support an editor placed inside a shadow root, the Uploadcare
uc-configanduc-upload-ctx-providerweb components are no longer appended todocument.body. They are added to the editor's body collection instead, so they are rendered wherever the editor's floating user interface is mounted. TheUploadcareEditing#configElementandUploadcareEditing#ctxElementproperties are unchanged and remain the way to access them.utils: The
getCommonAncestor()DOM utility function has been removed from theckeditor5-utilspackage. It walkedparentNodechains, which stop at a shadow boundary, so it could not answer correctly for nodes inside a shadow root. To find the lowest common ancestor of two DOM nodes, walk their ancestors withgetParentNode()and compare the chains, or use the model and viewgetCommonAncestor()methods when working with the editor tree. See #3891.utils: The
getPositionedAncestor()DOM utility function now returnsnullfor an element that is not connected to a document, where it previously required only that the element had a parent. See #3891.
Features
core, fullscreen, ui: Introduced the
config.ui.overlayContaineroption: the element or shadow root that hosts the editor's floating user interface (balloons, dialogs, and tooltips). Point it at a container of your own when the editor lives inside a shadow root. The editor stylesheets have to be adopted into that container — see the "Styles inside a shadow DOM" section of the CSS guide. See #3891, #5319.The
config.fullscreen.containeroption accepts a shadow root as well now.ui, utils: Introduced the public API behind shadow DOM support, for features and integrations that resolve DOM access themselves: the
ShadowRootRegistryandOverlayHostclasses, theShadowSelectionclass together with thegetSelection()utility that returns it, theEditorUI#shadowRootRegistryproperty, and the mounting API ofBodyCollection, whoseattachToDom()method now accepts an element or a shadow root. See #3891.They come with shadow-aware replacements for the plain DOM traversal and hit-testing helpers, such as
getParentNode(),containsNode(),getActiveElement()andgetElementFromPoint(). See the API documentation of theckeditor5-utilspackage for the full list.comments, real-time-collaboration: Introduced the
config.sidebar.overlayContainerandconfig.presenceList.overlayContaineroptions: the element or shadow root that hosts the floating annotation balloon of the narrow sidebar and the floating presence list dropdown. Set one when the feature runs inside a shadow root, or when its own container clips the floating user interface; otherwise the sharedconfig.ui.overlayContaineris used, if there is one.ckeditor5: The editor can now be created inside a shadow root, open or closed: selection, focus, positioning, scrolling, drag and drop, and the floating user interface all work there. The premium features work in a shadow root as well. Closes #3891.
Because a shadow root is a separate styling boundary, the editor stylesheets have to be loaded into every root that holds editor user interface, and CSS variables have to be overridden on the shadow host rather than on
:root. See the "Styles inside a shadow DOM" section of the CSS guide.ai: The AI Chat and the AI Review Mode now display a loading skeleton during initialization instead of an empty panel.
ai: The AI agent now understands the document root it works on. It knows whether the root accepts inline content only and what element hosts it. The agent is also aware of the soft break (Shift+Enter) support in the editor.
core: Editor errors can now be observed with the
onEditorError()function. It reports errors that escape an editor, together with the editor or context they came from, and returns a function that unregisters the callback. It observes rather than intercepts: nothing is restarted, no editor data is kept or restored, and a reported error still reaches the console exactly as it would with no callback registered. This is the replacement for the Watchdog, which is removed in this major release.ui: The body collection into which the shared tooltip balloon is placed can be chosen now, through th
Source: ckeditor/ckeditor5