diff --git a/core/.stylelintrc.json b/core/.stylelintrc.json
index 1de82b94955e48c2d13651e8055efa189c7ac2da..1c5887df5fb5152ae1c837d36b03844b7df9e628 100644
--- a/core/.stylelintrc.json
+++ b/core/.stylelintrc.json
@@ -477,7 +477,7 @@
   "ignoreFiles": [
     "assets/vendor/**/*.css",
     "tests/Drupal/Tests/Core/Asset/css_test_files/**/*.css",
-    "modules/media/css/plugins/drupalmedia/ckeditor.drupalmedia.css",
+    "modules/ckeditor/css/plugins/drupalmedia/ckeditor.drupalmedia.css",
     "themes/stable/css/core/assets/vendor/**/*.css",
     "themes/stable9/css/core/assets/vendor/**/*.css",
     "themes/stable9/css/media/plugins/drupalmedia/ckeditor.drupalmedia.css"
diff --git a/core/modules/ckeditor/ckeditor.libraries.yml b/core/modules/ckeditor/ckeditor.libraries.yml
index 7c6fc2f933b55154c58c1c1a1473f3a548bfd4e7..f71b90c611df9efcc22db9c3ea48ac9a7242d322 100644
--- a/core/modules/ckeditor/ckeditor.libraries.yml
+++ b/core/modules/ckeditor/ckeditor.libraries.yml
@@ -90,3 +90,10 @@ drupal.ckeditor.language.admin:
     - core/jquery
     - core/drupal
     - core/drupal.vertical-tabs
+
+drupal.ckeditor.plugins.drupalmedia:
+  version: VERSION
+  js:
+    js/ckeditor.drupalmedia.theme.js: {}
+  dependencies:
+    - core/drupal
diff --git a/core/modules/media/css/plugins/drupalmedia/ckeditor.drupalmedia.css b/core/modules/ckeditor/css/plugins/drupalmedia/ckeditor.drupalmedia.css
similarity index 100%
rename from core/modules/media/css/plugins/drupalmedia/ckeditor.drupalmedia.css
rename to core/modules/ckeditor/css/plugins/drupalmedia/ckeditor.drupalmedia.css
diff --git a/core/modules/ckeditor/js/ckeditor.drupalmedia.theme.es6.js b/core/modules/ckeditor/js/ckeditor.drupalmedia.theme.es6.js
new file mode 100644
index 0000000000000000000000000000000000000000..fbc93079c2acbccba38484d19cb5c87eb4b0fcf0
--- /dev/null
+++ b/core/modules/ckeditor/js/ckeditor.drupalmedia.theme.es6.js
@@ -0,0 +1,17 @@
+/**
+ * @file
+ * Theme elements for the Media Embed CKEditor plugin.
+ */
+
+((Drupal) => {
+  /**
+   * Themes the edit button for a media embed.
+   *
+   * @return {string}
+   *   An HTML string to insert in the CKEditor.
+   */
+  Drupal.theme.mediaEmbedEditButton = () =>
+    `<button class="media-library-item__edit">${Drupal.t(
+      'Edit media',
+    )}</button>`;
+})(Drupal);
diff --git a/core/modules/ckeditor/js/ckeditor.drupalmedia.theme.js b/core/modules/ckeditor/js/ckeditor.drupalmedia.theme.js
new file mode 100644
index 0000000000000000000000000000000000000000..629422479f0f60aca5099a4c7ff73569b2aa3b30
--- /dev/null
+++ b/core/modules/ckeditor/js/ckeditor.drupalmedia.theme.js
@@ -0,0 +1,10 @@
+/**
+* DO NOT EDIT THIS FILE.
+* See the following change record for more information,
+* https://www.drupal.org/node/2815083
+* @preserve
+**/
+
+(Drupal => {
+  Drupal.theme.mediaEmbedEditButton = () => `<button class="media-library-item__edit">${Drupal.t('Edit media')}</button>`;
+})(Drupal);
\ No newline at end of file
diff --git a/core/modules/media/js/plugins/drupalmedia/plugin.es6.js b/core/modules/ckeditor/js/plugins/drupalmedia/plugin.es6.js
similarity index 100%
rename from core/modules/media/js/plugins/drupalmedia/plugin.es6.js
rename to core/modules/ckeditor/js/plugins/drupalmedia/plugin.es6.js
diff --git a/core/modules/media/js/plugins/drupalmedia/plugin.js b/core/modules/ckeditor/js/plugins/drupalmedia/plugin.js
similarity index 100%
rename from core/modules/media/js/plugins/drupalmedia/plugin.js
rename to core/modules/ckeditor/js/plugins/drupalmedia/plugin.js
diff --git a/core/modules/media/src/Plugin/CKEditorPlugin/DrupalMedia.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalMedia.php
similarity index 88%
rename from core/modules/media/src/Plugin/CKEditorPlugin/DrupalMedia.php
rename to core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalMedia.php
index d475f1ab9c7f12aac2ef4e0c2553efa10338b4b1..9365b096dcdb4173ca98decdae4ec14f86c81bc7 100644
--- a/core/modules/media/src/Plugin/CKEditorPlugin/DrupalMedia.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalMedia.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\media\Plugin\CKEditorPlugin;
+namespace Drupal\ckeditor\Plugin\CKEditorPlugin;
 
 use Drupal\ckeditor\CKEditorPluginContextualInterface;
 use Drupal\ckeditor\CKEditorPluginCssInterface;
@@ -16,6 +16,7 @@
  * @CKEditorPlugin(
  *   id = "drupalmedia",
  *   label = @Translation("Media Embed"),
+ *   provider = "media",
  * )
  *
  * @internal
@@ -83,7 +84,10 @@ public function getLibraries(Editor $editor) {
       'core/jquery',
       'core/drupal',
       'core/drupal.ajax',
+      // @see Drupal.theme.mediaEmbedPreviewError()
       'media/media_embed_ckeditor_theme',
+      // @see Drupal.theme.mediaEmbedEditButton()
+      'ckeditor/drupal.ckeditor.plugins.drupalmedia',
     ];
   }
 
@@ -91,7 +95,7 @@ public function getLibraries(Editor $editor) {
    * {@inheritdoc}
    */
   public function getFile() {
-    return $this->moduleExtensionList->getPath('media') . '/js/plugins/drupalmedia/plugin.js';
+    return $this->moduleExtensionList->getPath('ckeditor') . '/js/plugins/drupalmedia/plugin.js';
   }
 
   /**
@@ -124,7 +128,7 @@ public function isEnabled(Editor $editor) {
    */
   public function getCssFiles(Editor $editor) {
     return [
-      $this->moduleExtensionList->getPath('media') . '/css/plugins/drupalmedia/ckeditor.drupalmedia.css',
+      $this->moduleExtensionList->getPath('ckeditor') . '/css/plugins/drupalmedia/ckeditor.drupalmedia.css',
       $this->moduleExtensionList->getPath('system') . '/css/components/hidden.module.css',
     ];
   }
diff --git a/core/modules/media/tests/src/FunctionalJavascript/CKEditorIntegrationTest.php b/core/modules/ckeditor/tests/src/FunctionalJavascript/MediaTest.php
similarity index 99%
rename from core/modules/media/tests/src/FunctionalJavascript/CKEditorIntegrationTest.php
rename to core/modules/ckeditor/tests/src/FunctionalJavascript/MediaTest.php
index 53427a31012d5526494914310e159641cf6041e8..e68edebd81cd28204030bbb974d7eecb1b358a89 100644
--- a/core/modules/media/tests/src/FunctionalJavascript/CKEditorIntegrationTest.php
+++ b/core/modules/ckeditor/tests/src/FunctionalJavascript/MediaTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\Tests\media\FunctionalJavascript;
+namespace Drupal\Tests\ckeditor\FunctionalJavascript;
 
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Database\Database;
@@ -21,10 +21,10 @@
 use Drupal\Core\Entity\Entity\EntityViewMode;
 
 /**
- * @coversDefaultClass \Drupal\media\Plugin\CKEditorPlugin\DrupalMedia
- * @group media
+ * @coversDefaultClass \Drupal\ckeditor\Plugin\CKEditorPlugin\DrupalMedia
+ * @group ckeditor
  */
-class CKEditorIntegrationTest extends WebDriverTestBase {
+class MediaTest extends WebDriverTestBase {
 
   use CKEditorTestTrait;
   use MediaTypeCreationTrait;
diff --git a/core/modules/ckeditor5/ckeditor5.libraries.yml b/core/modules/ckeditor5/ckeditor5.libraries.yml
index 53554f8cbc1c3e9fcd7d6462f972b284a676d1e8..cbe1d455ccd7c0786b2d4de855467a8a7d0a3820 100644
--- a/core/modules/ckeditor5/ckeditor5.libraries.yml
+++ b/core/modules/ckeditor5/ckeditor5.libraries.yml
@@ -63,7 +63,6 @@ drupal.ckeditor5.emphasis:
 
 drupal.ckeditor5.media:
   js:
-    js/media_embed_ckeditor5.theme.js: {}
     js/build/drupalMedia.js: { minified: true }
   css:
     theme:
@@ -71,6 +70,7 @@ drupal.ckeditor5.media:
   dependencies:
     - core/ckeditor5
     - core/drupal
+    - media/media_embed_ckeditor_theme
 
 drupal.ckeditor5.mediaAlign:
   css:
diff --git a/core/modules/ckeditor5/ckeditor5.libraries.yml.orig b/core/modules/ckeditor5/ckeditor5.libraries.yml.orig
new file mode 100644
index 0000000000000000000000000000000000000000..53554f8cbc1c3e9fcd7d6462f972b284a676d1e8
--- /dev/null
+++ b/core/modules/ckeditor5/ckeditor5.libraries.yml.orig
@@ -0,0 +1,188 @@
+# cspell:ignore imageupload
+
+ckeditor5.language:
+  css:
+    component:
+      css/language.css: {}
+  dependencies:
+    - core/ckeditor5.language
+
+drupal.ckeditor5.internal:
+  js:
+    js/build/drupalHtmlEngine.js: { minified: true }
+  dependencies:
+    - core/ckeditor5
+    - core/ckeditor5.internal
+
+drupal.ckeditor5:
+  js:
+    js/ckeditor5.js: {}
+  dependencies:
+    - core/jquery
+    - core/once
+    - core/drupal
+    - core/drupal.debounce
+    - core/ckeditor5.editorClassic
+    - core/ckeditor5.editorDecoupled
+    - core/ckeditor5
+    - editor/drupal.editor
+    - ckeditor5/drupal.ckeditor5.stylesheets
+    - core/drupalSettings
+    - core/drupal.message
+
+# Library used for dynamically loading CKEditor 5 stylesheets from the default
+# front end theme.
+# @see ckeditor5_library_info_alter()
+drupal.ckeditor5.stylesheets:
+  version: VERSION
+  css: []
+
+drupal.ckeditor5.codeBlock:
+  dependencies:
+    - core/ckeditor5.codeBlock
+    - core/ckeditor5.htmlSupport
+
+drupal.ckeditor5.image:
+  js:
+    js/build/drupalImage.js: { minified: true }
+  css:
+    theme:
+      css/image.css: { }
+  dependencies:
+    - core/drupal
+    - core/ckeditor5
+    - core/ckeditor5.image
+
+drupal.ckeditor5.emphasis:
+  version: VERSION
+  js:
+    js/build/drupalEmphasis.js: { minified: true }
+  dependencies:
+    - core/ckeditor5
+    - core/ckeditor5.basic
+
+drupal.ckeditor5.media:
+  js:
+    js/media_embed_ckeditor5.theme.js: {}
+    js/build/drupalMedia.js: { minified: true }
+  css:
+    theme:
+      css/drupalmedia.css: { }
+  dependencies:
+    - core/ckeditor5
+    - core/drupal
+
+drupal.ckeditor5.mediaAlign:
+  css:
+    theme:
+      css/media-alignment.css: { }
+  dependencies:
+    - ckeditor5/drupal.ckeditor5.media
+
+drupal.ckeditor5.filter.admin:
+  js:
+    js/ckeditor5.filter.admin.js: {}
+  dependencies:
+    - core/drupal
+    - core/once
+    - core/drupal.ajax
+    - core/drupalSettings
+
+admin:
+  js:
+    js/ckeditor5.admin.js: { }
+  css:
+    theme:
+      css/toolbar.admin.css: { }
+  dependencies:
+    - core/sortable
+    - filter/drupal.filter.admin
+    - core/jquery
+    - core/once
+
+admin.specialCharacters:
+  css:
+    theme:
+      css/special-characters.css: { }
+
+admin.removeFormat:
+  css:
+    theme:
+      css/remove-format.css: { }
+
+admin.internal:
+  css:
+    theme:
+      css/internal.admin.css: { }
+
+admin.basic:
+  css:
+    theme:
+      css/basic.admin.css: { }
+
+admin.blockquote:
+  css:
+    theme:
+      css/blockquote.admin.css: { }
+
+admin.link:
+  css:
+    theme:
+      css/link.admin.css: { }
+
+admin.list:
+  css:
+    theme:
+      css/list.admin.css: { }
+
+admin.heading:
+  css:
+    theme:
+      css/heading.admin.css: { }
+  dependencies:
+    - core/ckeditor5.internal
+
+admin.horizontalLine:
+  css:
+    theme:
+      css/horizontal-line.admin.css: { }
+
+admin.alignment:
+  css:
+    theme:
+      css/alignment.admin.css: { }
+
+admin.imageupload:
+  css:
+    theme:
+      css/imageupload.admin.css: { }
+
+admin.indent:
+  css:
+    theme:
+      css/indent.admin.css: { }
+
+admin.language:
+  css:
+    theme:
+      css/language.admin.css: { }
+
+admin.drupalmedia:
+  css:
+    theme:
+      css/drupalmedia.admin.css: { }
+
+admin.sourceEditing:
+  css:
+    theme:
+      css/source-editing.admin.css: { }
+
+admin.table:
+  css:
+    theme:
+      css/table.admin.css: { }
+
+admin.codeBlock:
+  css:
+    theme:
+      css/code-block.admin.css: { }
diff --git a/core/modules/ckeditor5/js/media_embed_ckeditor5.theme.es6.js b/core/modules/ckeditor5/js/media_embed_ckeditor5.theme.es6.js
deleted file mode 100644
index ee9dbbef7b550e7067822ab7371c36c104f47ec1..0000000000000000000000000000000000000000
--- a/core/modules/ckeditor5/js/media_embed_ckeditor5.theme.es6.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * @file
- * Theme elements for the Media Embed CKEditor5 plugin.
- */
-
-((Drupal) => {
-  /**
-   * Themes the error displayed when the media embed preview fails.
-   *
-   * @return {string}
-   *   A string representing a DOM fragment.
-   *
-   * @see media-embed-error.html.twig
-   */
-  Drupal.theme.mediaEmbedPreviewError = () =>
-    `<div>${Drupal.t(
-      'An error occurred while trying to preview the media. Please save your work and reload this page.',
-    )}</div>`;
-})(Drupal);
diff --git a/core/modules/ckeditor5/js/media_embed_ckeditor5.theme.js b/core/modules/ckeditor5/js/media_embed_ckeditor5.theme.js
deleted file mode 100644
index bcacbb8bb5bb1e097f1e603b4c91d928daf808e7..0000000000000000000000000000000000000000
--- a/core/modules/ckeditor5/js/media_embed_ckeditor5.theme.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
-* DO NOT EDIT THIS FILE.
-* See the following change record for more information,
-* https://www.drupal.org/node/2815083
-* @preserve
-**/
-
-(Drupal => {
-  Drupal.theme.mediaEmbedPreviewError = () => `<div>${Drupal.t('An error occurred while trying to preview the media. Please save your work and reload this page.')}</div>`;
-})(Drupal);
\ No newline at end of file
diff --git a/core/modules/media/js/media_embed_ckeditor.theme.es6.js b/core/modules/media/js/media_embed_ckeditor.theme.es6.js
index 52ef82aa7d7c8527b694aef1ad6de3c3a37e2bb1..bb2bd6dcda474852197a07c17f24f50453e9f310 100644
--- a/core/modules/media/js/media_embed_ckeditor.theme.es6.js
+++ b/core/modules/media/js/media_embed_ckeditor.theme.es6.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Theme elements for the Media Embed CKEditor plugin.
+ * Theme elements for the Media Embed text editor plugins.
  */
 
 ((Drupal) => {
@@ -16,15 +16,4 @@
     `<div>${Drupal.t(
       'An error occurred while trying to preview the media. Please save your work and reload this page.',
     )}</div>`;
-
-  /**
-   * Themes the edit button for a media embed.
-   *
-   * @return {string}
-   *   An HTML string to insert in the CKEditor.
-   */
-  Drupal.theme.mediaEmbedEditButton = () =>
-    `<button class="media-library-item__edit">${Drupal.t(
-      'Edit media',
-    )}</button>`;
 })(Drupal);
diff --git a/core/modules/media/js/media_embed_ckeditor.theme.js b/core/modules/media/js/media_embed_ckeditor.theme.js
index 7a63f1120ff0f943e953522ceafafa5001330d2c..bcacbb8bb5bb1e097f1e603b4c91d928daf808e7 100644
--- a/core/modules/media/js/media_embed_ckeditor.theme.js
+++ b/core/modules/media/js/media_embed_ckeditor.theme.js
@@ -7,6 +7,4 @@
 
 (Drupal => {
   Drupal.theme.mediaEmbedPreviewError = () => `<div>${Drupal.t('An error occurred while trying to preview the media. Please save your work and reload this page.')}</div>`;
-
-  Drupal.theme.mediaEmbedEditButton = () => `<button class="media-library-item__edit">${Drupal.t('Edit media')}</button>`;
 })(Drupal);
\ No newline at end of file
diff --git a/core/modules/media/media.libraries.yml b/core/modules/media/media.libraries.yml
index efc9dd1ada24f71bf41c45314294df6354c0d015..f8febc4dfcb40ff75d5a05ae920cc52f6eb9ab11 100644
--- a/core/modules/media/media.libraries.yml
+++ b/core/modules/media/media.libraries.yml
@@ -32,6 +32,8 @@ filter.caption:
   dependencies:
     - filter/caption
 
+# Despite the name, this is actually not specific to CKEditor 4, and can be
+# used by all text editor plugins.
 media_embed_ckeditor_theme:
   version: VERSION
   js:
diff --git a/core/modules/media/media.module b/core/modules/media/media.module
index b4d3112e9c6d016383ecdda84561b76ac5280213..30b219e579166efbe97433e282fdda895690a220 100644
--- a/core/modules/media/media.module
+++ b/core/modules/media/media.module
@@ -510,9 +510,9 @@ function media_filter_format_edit_form_validate($form, FormStateInterface $form_
  * Implements hook_field_widget_single_element_form_alter().
  */
 function media_field_widget_single_element_form_alter(&$element, FormStateInterface $form_state, $context) {
-  // Add an attribute so that "drupalmedia" CKEditor plugin can pass the host
-  // entity's language to EditorMediaDialog, allowing it to present entities
-  // in the same language.
+  // Add an attribute so that text editors plugins can pass the host entity's
+  // language to EditorMediaDialog, allowing it to present entities in the same
+  // language.
   if (!empty($element['#type']) && $element['#type'] == 'text_format') {
     $element['#attributes']['data-media-embed-host-entity-langcode'] = $context['items']->getLangcode();
   }
diff --git a/core/modules/media/src/Form/EditorMediaDialog.php b/core/modules/media/src/Form/EditorMediaDialog.php
index 65f2d59865051ca211ba6af6158b5180d31a6f61..8a961df6d23a74380a4befb0fe05a9f3febe48e5 100644
--- a/core/modules/media/src/Form/EditorMediaDialog.php
+++ b/core/modules/media/src/Form/EditorMediaDialog.php
@@ -96,7 +96,6 @@ public function buildForm(array $form, FormStateInterface $form_state, EditorInt
       $editor_object = $form_state->getUserInput()['editor_object'];
       // The data that the text editor sends to any dialog is in
       // the 'editor_object' key.
-      // @see core/modules/ckeditor/js/ckeditor.es6.js
       $media_embed_element = $editor_object['attributes'];
       $form_state->set('media_embed_element', $media_embed_element);
       $has_caption = $editor_object['hasCaption'];
diff --git a/core/modules/media/tests/modules/media_test_embed/media_test_embed.info.yml b/core/modules/media/tests/modules/media_test_embed/media_test_embed.info.yml
index a06c93a927550e39c578db28e23f44a616ce9b8b..eb7ca8827431d08dbca999a95dc020ce1bdd1411 100644
--- a/core/modules/media/tests/modules/media_test_embed/media_test_embed.info.yml
+++ b/core/modules/media/tests/modules/media_test_embed/media_test_embed.info.yml
@@ -1,5 +1,5 @@
-name: Media Embed plugin test
-description: 'Provides functionality to test embedding media items in CKEditor.'
+name: Media Embed text editor plugin test
+description: 'Provides functionality to test embedding media items in text editors.'
 type: module
 package: Testing
 version: VERSION
diff --git a/core/modules/media/tests/modules/media_test_embed/media_test_embed.module b/core/modules/media/tests/modules/media_test_embed/media_test_embed.module
index 2b8071ccf4394943a6babd260a09e60815e83658..35add70f03014b4957d55deca6e943ac8625c9ed 100644
--- a/core/modules/media/tests/modules/media_test_embed/media_test_embed.module
+++ b/core/modules/media/tests/modules/media_test_embed/media_test_embed.module
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Helper module for the Media Embed CKEditor plugin tests.
+ * Helper module for the Media Embed text editor plugin tests.
  */
 
 use Drupal\Core\Access\AccessResult;
@@ -14,7 +14,6 @@
  * Implements hook_entity_view_alter().
  */
 function media_test_embed_entity_view_alter(&$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
-  // @see \Drupal\Tests\media\FunctionalJavascript\CKEditorIntegrationTest::testPreviewUsesDefaultThemeAndIsClientCacheable()
   $build['#attributes']['data-media-embed-test-active-theme'] = \Drupal::theme()->getActiveTheme()->getName();
   $build['#attributes']['data-media-embed-test-view-mode'] = $display->getMode();
 }
diff --git a/core/modules/media/tests/modules/media_test_embed/src/Controller/TestMediaFilterController.php b/core/modules/media/tests/modules/media_test_embed/src/Controller/TestMediaFilterController.php
index f1173450d4f4dcadb13a59deea7519c5829fa2df..09b926dba4877eb95b7b1464e7227673198781c9 100644
--- a/core/modules/media/tests/modules/media_test_embed/src/Controller/TestMediaFilterController.php
+++ b/core/modules/media/tests/modules/media_test_embed/src/Controller/TestMediaFilterController.php
@@ -8,7 +8,7 @@
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
 /**
- * Controller to allow testing of error handling in drupalmedia plugin.js.
+ * Controller to allow testing of error handling of Media Embed in text editors.
  */
 class TestMediaFilterController extends MediaFilterController {
 
diff --git a/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php b/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php
index 4483b89b3d44068cfd702557f04f3d4b1f3b8087..e2b4b820ad8dfddf573936bb82429214fe1ccdf0 100644
--- a/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php
+++ b/core/modules/media/tests/src/Kernel/MediaEmbedFilterTest.php
@@ -356,8 +356,6 @@ public function providerMissingEntityIndicator() {
 
   /**
    * Tests that only <drupal-media> tags are processed.
-   *
-   * @see \Drupal\Tests\media\FunctionalJavascript\CKEditorIntegrationTest::testOnlyDrupalMediaTagProcessed()
    */
   public function testOnlyDrupalMediaTagProcessed() {
     $content = $this->createEmbedCode([