From e1e95969a10bd8f27977bb6d96140d0835e9ab9b Mon Sep 17 00:00:00 2001
From: Lee Rowlands <lee.rowlands@previousnext.com.au>
Date: Thu, 28 Mar 2024 07:19:28 +1000
Subject: [PATCH] Issue #3352256 by e0ipso, plopesc, bbrala, longwave, dww,
 catch, larowlan: Move code from the experimental SDC module to core

---
 core/.eslintignore                            |   2 +-
 .../schemas/v1}/metadata-full.schema.json     |   2 +-
 .../schemas/v1}/metadata.schema.json          |   2 +-
 core/core.services.yml                        |  35 +++++-
 .../Core/Asset/LibraryDiscoveryParser.php     |  56 +++++++++-
 .../Drupal/Core}/Plugin/Component.php         |  17 ++-
 .../DirectoryWithMetadataDiscovery.php        |   6 +-
 .../DirectoryWithMetadataPluginDiscovery.php  |   9 +-
 .../RegexRecursiveFilterIterator.php          |   8 +-
 .../Exception/ComponentNotFoundException.php  |  12 ++
 .../Exception/IncompatibleComponentSchema.php |  12 ++
 .../InvalidComponentDataException.php         |  12 ++
 .../Exception/InvalidComponentException.php   |  12 ++
 core/lib/Drupal/Core/Render/Element.php       |  30 +++++
 .../Core/Render}/Element/ComponentElement.php |  16 +--
 .../Core/Template}/ComponentNodeVisitor.php   |  24 ++--
 .../Template/ComponentsTwigExtension.php}     |  45 ++++----
 .../Core/Template/Loader/ComponentLoader.php} |  16 ++-
 .../Theme}/Component/ComponentMetadata.php    |  12 +-
 .../Theme}/Component/ComponentValidator.php   |  24 ++--
 .../Component/SchemaCompatibilityChecker.php  |  10 +-
 .../Core/Theme}/ComponentNegotiator.php       |  28 ++---
 .../Core/Theme}/ComponentPluginManager.php    |  72 +++++-------
 .../Drupal/Core/Theme}/ExtensionType.php      |   2 +-
 core/modules/sdc/README.txt                   |   2 +-
 core/modules/sdc/sdc.info.yml                 |   3 +-
 core/modules/sdc/sdc.module                   |  87 ++++++---------
 core/modules/sdc/sdc.services.yml             |  76 ++++++-------
 .../Exception/ComponentNotFoundException.php  |  12 --
 .../Exception/IncompatibleComponentSchema.php |  12 --
 .../InvalidComponentDataException.php         |  12 --
 .../Exception/InvalidComponentException.php   |  12 --
 core/modules/sdc/src/Utilities.php            |  51 ---------
 .../no-props/no-props.component.yml           |   6 -
 .../my-card-no-schema.component.yml           |   3 -
 .../sdc/tests/src/Functional/GenericTest.php  |  14 ---
 .../src/Functional/LibrariesBCLayerTest.php   |  45 ++++++++
 .../src/Kernel/ComponentKernelTestBase.php    |  74 ------------
 .../src/Traits/ComponentRendererTrait.php     |  47 --------
 .../sdc/tests/src/Unit/UtilitiesTest.php      |  41 -------
 .../my-card-no-schema.component.yml           |   3 -
 .../my-card-no-schema.component.yml           |   3 -
 .../sdc_other_node_visitor.info.yml           |   2 -
 .../sdc_other_node_visitor.services.yml       |   0
 .../Twig/Extension/TestProfilerExtension.php  |   0
 .../src/Twig/NodeVisitor/TestNodeVisitor.php  |   0
 .../src/Twig/Profiler/EnterProfileNode.php    |   0
 .../src/Twig/Profiler/LeaveProfileNode.php    |   0
 .../array-to-object.component.yml             |   2 +-
 .../array-to-object/array-to-object.twig      |   0
 .../my-banner/my-banner.component.yml         |   2 +-
 .../components/my-banner/my-banner.css        |   0
 .../components/my-banner/my-banner.twig       |   0
 .../my-button/my-button.component.yml         |   2 +-
 .../components/my-button/my-button.css        |   0
 .../components/my-button/my-button.js         |   0
 .../components/my-button/my-button.twig       |   0
 .../components/my-cta/my-cta.component.yml    |   2 +-
 .../sdc_test/components/my-cta/my-cta.css     |   0
 .../sdc_test/components/my-cta/my-cta.js      |   0
 .../sdc_test/components/my-cta/my-cta.twig    |   0
 .../no-props/no-props.component.yml           |   6 +
 .../components/no-props/no-props.twig         |   0
 .../tests/modules/sdc_test/sdc_test.info.yml  |   2 -
 .../modules/sdc_test/sdc_test.routing.yml     |   0
 .../Controller/ServerEndpointController.php   |   0
 .../my-card-no-schema.component.yml           |   3 +
 .../my-card-no-schema/my-card-no-schema.twig  |   0
 .../sdc_test_invalid.info.yml                 |   2 -
 .../my-button/my-button.component.yml         |   2 +-
 .../components/my-button/my-button.css        |   0
 .../components/my-button/my-button.js         |   0
 .../components/my-button/my-button.twig       |   0
 .../sdc_test_replacements.info.yml            |   2 -
 .../components/foo/foo.component.yml          |   2 +-
 .../components/foo/foo.twig                   |   0
 .../sdc_test_replacements_invalid.info.yml    |   2 -
 .../components/bar/bar.component.yml          |   0
 .../sdc_theme_test/components/bar/bar.twig    |   0
 .../lib-overrides/another-stylesheet.css      |   0
 .../lib-overrides/lib-overrides.component.yml |   2 +-
 .../lib-overrides/lib-overrides.css           |   0
 .../components/lib-overrides/lib-overrides.js |   0
 .../lib-overrides/lib-overrides.twig          |   0
 .../mismatching-folder-name/foo.component.yml |   2 +-
 .../mismatching-folder-name/foo.twig          |   0
 .../components/my-card/my-card.component.yml  |   2 +-
 .../components/my-card/my-card.css            |   0
 .../components/my-card/my-card.twig           |   0
 .../sdc_theme_test/sdc_theme_test.info.yml    |   0
 .../my-card-no-schema.component.yml           |   3 +
 .../my-card-no-schema/my-card-no-schema.twig  |   0
 .../sdc_theme_test_base.info.yml              |   0
 .../components/my-card/my-card.component.yml  |   2 +-
 .../components/my-card/my-card.css            |   0
 .../components/my-card/my-card.twig           |   0
 .../sdc_theme_test_enforce_schema.info.yml    |   0
 .../my-card-no-schema.component.yml           |   3 +
 .../my-card-no-schema/my-card-no-schema.twig  |   0
 ...theme_test_enforce_schema_invalid.info.yml |   0
 core/profiles/demo_umami/demo_umami.info.yml  |   1 -
 .../components/badge/badge.component.yml      |   2 +-
 .../components/banner/banner.component.yml    |   2 +-
 .../branding/branding.component.yml           |   2 +-
 .../umami/components/card/card.component.yml  |   2 +-
 .../disclaimer/disclaimer.component.yml       |   2 +-
 .../footer-block/footer-block.component.yml   |   2 +-
 .../components/header/header.component.yml    |   2 +-
 .../read-more/read-more.component.yml         |   2 +-
 .../components/title/title.component.yml      |   2 +-
 .../demo_umami/themes/umami/umami.info.yml    |   2 -
 .../Components}/ComponentRenderTest.php       |   8 +-
 .../Components}/ComponentRenderTest.php       |   8 +-
 .../ComponentInvalidReplacementTest.php       |   9 +-
 .../Components}/ComponentNodeVisitorTest.php  |  12 +-
 .../ComponentRenderInvalidTest.php            |   9 +-
 .../Components}/ComponentRenderTest.php       |  19 ++--
 .../Core/Asset/LibraryDiscoveryParserTest.php |  19 +++-
 .../Core/Extension/GenericTestExistsTest.php  |   2 +-
 .../Drupal/Tests/Core/Render/ElementTest.php  |  22 ++++
 .../Component/ComponentKernelTestBase.php     | 105 ++++++++++++++++++
 .../Component}/ComponentMetadataTest.php      |  18 ++-
 .../Component}/ComponentNegotiatorTest.php    |  10 +-
 .../Component}/ComponentPluginManagerTest.php |  10 +-
 .../Component}/ComponentValidatorTest.php     |  22 ++--
 .../SchemaCompatibilityCheckerTest.php        |  12 +-
 126 files changed, 647 insertions(+), 671 deletions(-)
 rename core/{modules/sdc/src => assets/schemas/v1}/metadata-full.schema.json (97%)
 rename core/{modules/sdc/src => assets/schemas/v1}/metadata.schema.json (97%)
 rename core/{modules/sdc/src => lib/Drupal/Core}/Plugin/Component.php (83%)
 rename core/{modules/sdc/src => lib/Drupal/Core}/Plugin/Discovery/DirectoryWithMetadataDiscovery.php (96%)
 rename core/{modules/sdc/src => lib/Drupal/Core}/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php (80%)
 rename core/{modules/sdc/src => lib/Drupal/Core}/Plugin/Discovery/RegexRecursiveFilterIterator.php (86%)
 create mode 100644 core/lib/Drupal/Core/Render/Component/Exception/ComponentNotFoundException.php
 create mode 100644 core/lib/Drupal/Core/Render/Component/Exception/IncompatibleComponentSchema.php
 create mode 100644 core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentDataException.php
 create mode 100644 core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentException.php
 rename core/{modules/sdc/src => lib/Drupal/Core/Render}/Element/ComponentElement.php (89%)
 rename core/{modules/sdc/src/Twig => lib/Drupal/Core/Template}/ComponentNodeVisitor.php (91%)
 rename core/{modules/sdc/src/Twig/TwigExtension.php => lib/Drupal/Core/Template/ComponentsTwigExtension.php} (65%)
 rename core/{modules/sdc/src/Twig/TwigComponentLoader.php => lib/Drupal/Core/Template/Loader/ComponentLoader.php} (91%)
 rename core/{modules/sdc/src => lib/Drupal/Core/Theme}/Component/ComponentMetadata.php (94%)
 rename core/{modules/sdc/src => lib/Drupal/Core/Theme}/Component/ComponentValidator.php (94%)
 rename core/{modules/sdc/src => lib/Drupal/Core/Theme}/Component/SchemaCompatibilityChecker.php (96%)
 rename core/{modules/sdc/src => lib/Drupal/Core/Theme}/ComponentNegotiator.php (90%)
 rename core/{modules/sdc/src => lib/Drupal/Core/Theme}/ComponentPluginManager.php (88%)
 rename core/{modules/sdc/src => lib/Drupal/Core/Theme}/ExtensionType.php (90%)
 delete mode 100644 core/modules/sdc/src/Exception/ComponentNotFoundException.php
 delete mode 100644 core/modules/sdc/src/Exception/IncompatibleComponentSchema.php
 delete mode 100644 core/modules/sdc/src/Exception/InvalidComponentDataException.php
 delete mode 100644 core/modules/sdc/src/Exception/InvalidComponentException.php
 delete mode 100644 core/modules/sdc/src/Utilities.php
 delete mode 100644 core/modules/sdc/tests/modules/sdc_test/components/no-props/no-props.component.yml
 delete mode 100644 core/modules/sdc/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
 delete mode 100644 core/modules/sdc/tests/src/Functional/GenericTest.php
 create mode 100644 core/modules/sdc/tests/src/Functional/LibrariesBCLayerTest.php
 delete mode 100644 core/modules/sdc/tests/src/Kernel/ComponentKernelTestBase.php
 delete mode 100644 core/modules/sdc/tests/src/Traits/ComponentRendererTrait.php
 delete mode 100644 core/modules/sdc/tests/src/Unit/UtilitiesTest.php
 delete mode 100644 core/modules/sdc/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml
 delete mode 100644 core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
 rename core/modules/{sdc => system}/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml (70%)
 rename core/modules/{sdc => system}/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml (52%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/array-to-object/array-to-object.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-banner/my-banner.component.yml (88%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-banner/my-banner.css (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-banner/my-banner.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-button/my-button.component.yml (82%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-button/my-button.css (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-button/my-button.js (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-button/my-button.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-cta/my-cta.component.yml (82%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-cta/my-cta.css (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-cta/my-cta.js (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/my-cta/my-cta.twig (100%)
 create mode 100644 core/modules/system/tests/modules/sdc_test/components/no-props/no-props.component.yml
 rename core/modules/{sdc => system}/tests/modules/sdc_test/components/no-props/no-props.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/sdc_test.info.yml (67%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/sdc_test.routing.yml (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test/src/Controller/ServerEndpointController.php (100%)
 create mode 100644 core/modules/system/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
 rename core/modules/{sdc => system}/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml (67%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml (82%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements/components/my-button/my-button.css (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements/components/my-button/my-button.js (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements/components/my-button/my-button.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml (72%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml (60%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements_invalid/components/foo/foo.twig (100%)
 rename core/modules/{sdc => system}/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml (74%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/bar/bar.component.yml (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/bar/bar.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/lib-overrides/another-stylesheet.css (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml (76%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.css (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.js (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml (55%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml (77%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/my-card/my-card.css (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/components/my-card/my-card.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test/sdc_theme_test.info.yml (100%)
 create mode 100644 core/modules/system/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_base/sdc_theme_test_base.info.yml (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml (78%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.css (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_enforce_schema/sdc_theme_test_enforce_schema.info.yml (100%)
 create mode 100644 core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.twig (100%)
 rename core/modules/{sdc => system}/tests/themes/sdc_theme_test_enforce_schema_invalid/sdc_theme_test_enforce_schema_invalid.info.yml (100%)
 rename core/{modules/sdc/tests/src/FunctionalJavascript => tests/Drupal/FunctionalJavascriptTests/Components}/ComponentRenderTest.php (90%)
 rename core/{modules/sdc/tests/src/Functional => tests/Drupal/FunctionalTests/Components}/ComponentRenderTest.php (90%)
 rename core/{modules/sdc/tests/src/Kernel => tests/Drupal/KernelTests/Components}/ComponentInvalidReplacementTest.php (67%)
 rename core/{modules/sdc/tests/src/Kernel => tests/Drupal/KernelTests/Components}/ComponentNodeVisitorTest.php (67%)
 rename core/{modules/sdc/tests/src/Kernel => tests/Drupal/KernelTests/Components}/ComponentRenderInvalidTest.php (87%)
 rename core/{modules/sdc/tests/src/Kernel => tests/Drupal/KernelTests/Components}/ComponentRenderTest.php (94%)
 create mode 100644 core/tests/Drupal/Tests/Core/Theme/Component/ComponentKernelTestBase.php
 rename core/{modules/sdc/tests/src/Unit => tests/Drupal/Tests/Core/Theme/Component}/ComponentMetadataTest.php (89%)
 rename core/{modules/sdc/tests/src/Kernel => tests/Drupal/Tests/Core/Theme/Component}/ComponentNegotiatorTest.php (91%)
 rename core/{modules/sdc/tests/src/Kernel => tests/Drupal/Tests/Core/Theme/Component}/ComponentPluginManagerTest.php (83%)
 rename core/{modules/sdc/tests/src/Unit => tests/Drupal/Tests/Core/Theme/Component}/ComponentValidatorTest.php (89%)
 rename core/{modules/sdc/tests/src/Unit => tests/Drupal/Tests/Core/Theme/Component}/SchemaCompatibilityCheckerTest.php (90%)

diff --git a/core/.eslintignore b/core/.eslintignore
index 570792e1b3e6..223205a2ada8 100644
--- a/core/.eslintignore
+++ b/core/.eslintignore
@@ -11,7 +11,7 @@ tests/Drupal/Tests/Core/Asset/library_test_files/empty.libraries.yml
 tests/Drupal/Tests/Core/Asset/library_test_files/invalid_file.libraries.yml
 tests/Drupal/Tests/Composer/Plugin/Scaffold/fixtures/drupal-assets-fixture/assets/default.services.yml
 tests/Drupal/Tests/Composer/Plugin/Scaffold/fixtures/drupal-profile/assets/profile.default.services.yml
-modules/sdc/tests/themes/sdc_theme_test/components/bar/bar.component.yml
+modules/system/tests/themes/sdc_theme_test/components/bar/bar.component.yml
 
 # Temporary until they are brought up to standards
 scripts/**/*
diff --git a/core/modules/sdc/src/metadata-full.schema.json b/core/assets/schemas/v1/metadata-full.schema.json
similarity index 97%
rename from core/modules/sdc/src/metadata-full.schema.json
rename to core/assets/schemas/v1/metadata-full.schema.json
index d53f5a9befb3..8df83fb05c96 100644
--- a/core/modules/sdc/src/metadata-full.schema.json
+++ b/core/assets/schemas/v1/metadata-full.schema.json
@@ -1,5 +1,5 @@
 {
-  "$id": "https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json",
+  "$id": "https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata-full.schema.json",
   "$schema": "http://json-schema.org/draft-04/schema#",
   "$defs": {
     "slotDefinition": {
diff --git a/core/modules/sdc/src/metadata.schema.json b/core/assets/schemas/v1/metadata.schema.json
similarity index 97%
rename from core/modules/sdc/src/metadata.schema.json
rename to core/assets/schemas/v1/metadata.schema.json
index b22360b84c52..4cbeffebff1b 100644
--- a/core/modules/sdc/src/metadata.schema.json
+++ b/core/assets/schemas/v1/metadata.schema.json
@@ -1,5 +1,5 @@
 {
-  "$id": "https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json",
+  "$id": "https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json",
   "$schema": "http://json-schema.org/draft-04/schema#",
   "$defs": {
     "slotDefinition": {
diff --git a/core/core.services.yml b/core/core.services.yml
index 22cb21e24dea..6442cae48c7a 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1684,7 +1684,7 @@ services:
       - { name: needs_destruction }
   library.discovery.parser:
     class: Drupal\Core\Asset\LibraryDiscoveryParser
-    arguments: ['%app.root%', '@module_handler', '@theme.manager', '@stream_wrapper_manager', '@library.libraries_directory_file_finder', '@extension.path.resolver']
+    arguments: ['%app.root%', '@module_handler', '@theme.manager', '@stream_wrapper_manager', '@library.libraries_directory_file_finder', '@extension.path.resolver', '@plugin.manager.sdc']
   Drupal\Core\Asset\LibraryDiscoveryParser: '@library.discovery.parser'
   library.libraries_directory_file_finder:
     class: Drupal\Core\Asset\LibrariesDirectoryFileFinder
@@ -1713,6 +1713,10 @@ services:
     arguments: ['@renderer', '@url_generator', '@theme.manager', '@date.formatter', '@file_url_generator']
     tags:
       - { name: twig.extension, priority: 100 }
+  Drupal\Core\Template\ComponentsTwigExtension:
+    arguments: ['@plugin.manager.sdc', '@Drupal\Core\Theme\Component\ComponentValidator']
+    tags:
+      - { name: twig.extension, priority: 101 }
   twig.extension.debug:
     class: Twig\Extension\DebugExtension
     tags:
@@ -1845,3 +1849,32 @@ services:
     class: Drupal\Core\Pager\PagerParameters
     arguments: ['@request_stack']
   Drupal\Core\Pager\PagerParametersInterface: '@pager.parameters'
+  Drupal\Core\Theme\Component\SchemaCompatibilityChecker: {}
+  Drupal\Core\Theme\Component\ComponentValidator:
+    calls:
+      - [setValidator, []]
+  Drupal\Core\Theme\ComponentNegotiator:
+    arguments:
+      - '@theme.manager'
+      - '@extension.list.module'
+  plugin.manager.sdc:
+    public: true
+    class: Drupal\Core\Theme\ComponentPluginManager
+    arguments:
+      - '@module_handler'
+      - '@theme_handler'
+      - '@cache.discovery'
+      - '@config.factory'
+      - '@theme.manager'
+      - '@Drupal\Core\Theme\ComponentNegotiator'
+      - '@file_system'
+      - '@Drupal\Core\Theme\Component\SchemaCompatibilityChecker'
+      - '@Drupal\Core\Theme\Component\ComponentValidator'
+      - '%app.root%'
+  Drupal\Core\Theme\ComponentPluginManager: '@plugin.manager.sdc'
+  Drupal\Core\Template\Loader\ComponentLoader:
+    arguments:
+      - '@plugin.manager.sdc'
+      - '@logger.channel.default'
+    tags:
+      - { name: twig.loader, priority: 5 }
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 0114e9a96bb9..a5722b41f5e6 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -14,7 +14,9 @@
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\Core\Theme\ThemeManagerInterface;
+use Drupal\Core\Plugin\Component;
 
 /**
  * Parses library files to get extension data.
@@ -56,6 +58,13 @@ class LibraryDiscoveryParser {
    */
   protected $librariesDirectoryFileFinder;
 
+  /**
+   * The component plugin manager.
+   *
+   * @var \Drupal\Core\Theme\ComponentPluginManager
+   */
+  protected $componentPluginManager;
+
   /**
    * The extension path resolver.
    *
@@ -85,8 +94,10 @@ class LibraryDiscoveryParser {
    *   The libraries directory file finder.
    * @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
    *   The extension path resolver.
+   * @param \Drupal\Core\Theme\ComponentPluginManager|null $component_plugin_manager
+   *   The component plugin manager.
    */
-  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, StreamWrapperManagerInterface $stream_wrapper_manager, LibrariesDirectoryFileFinder $libraries_directory_file_finder, ExtensionPathResolver $extension_path_resolver) {
+  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, StreamWrapperManagerInterface $stream_wrapper_manager, LibrariesDirectoryFileFinder $libraries_directory_file_finder, ExtensionPathResolver $extension_path_resolver, ?ComponentPluginManager $component_plugin_manager = NULL) {
     $this->root = $root;
     $this->moduleHandler = $module_handler;
     $this->themeManager = $theme_manager;
@@ -94,6 +105,11 @@ public function __construct($root, ModuleHandlerInterface $module_handler, Theme
     $this->librariesDirectoryFileFinder = $libraries_directory_file_finder;
     $this->extensionPathResolver = $extension_path_resolver;
     $this->fileCache = FileCacheFactory::get('library_parser');
+    if (!isset($component_plugin_manager)) {
+      @trigger_error('Calling ' . __METHOD__ . '() without the $component_plugin_manager argument is deprecated in drupal:10.3.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3410260', E_USER_DEPRECATED);
+      $component_plugin_manager = \Drupal::service('plugin.manager.sdc');
+    }
+    $this->componentPluginManager = $component_plugin_manager;
   }
 
   /**
@@ -383,6 +399,13 @@ protected function parseLibraryInfo($extension, $path) {
         }
       }
     }
+    // Core also provides additional libraries that don't come from the YAML,
+    // file nor the hook_library_info_build. They come from single directory
+    // component definitions.
+    $additional_libraries = $extension === 'core'
+      ? $this->librariesForComponents()
+      : [];
+    $libraries = array_merge($additional_libraries, $libraries);
 
     // Allow modules to add dynamic library definitions.
     $hook = 'library_info_build';
@@ -397,6 +420,37 @@ protected function parseLibraryInfo($extension, $path) {
     return $libraries;
   }
 
+  /**
+   * Builds the dynamic library definitions for single directory components.
+   *
+   * @return array
+   *   The core library definitions for Single Directory Components.
+   */
+  protected function librariesForComponents(): array {
+    // Iterate over all the components to get the CSS and JS files.
+    $components = $this->componentPluginManager->getAllComponents();
+    $libraries = array_reduce(
+      $components,
+      static function (array $libraries, Component $component) {
+        $library = $component->library;
+        if (empty($library)) {
+          return $libraries;
+        }
+        $library_name = $component->getLibraryName();
+        [, $library_id] = explode('/', $library_name);
+        return array_merge($libraries, [$library_id => $library]);
+      },
+      []
+    );
+    $libraries['components.all'] = [
+      'dependencies' => array_map(
+        static fn(Component $component) => $component->getLibraryName(),
+        $components
+      ),
+    ];
+    return $libraries;
+  }
+
   /**
    * Apply libraries overrides specified for the current active theme.
    *
diff --git a/core/modules/sdc/src/Plugin/Component.php b/core/lib/Drupal/Core/Plugin/Component.php
similarity index 83%
rename from core/modules/sdc/src/Plugin/Component.php
rename to core/lib/Drupal/Core/Plugin/Component.php
index 8fc3f22a1e9f..8d900ccaab7f 100644
--- a/core/modules/sdc/src/Plugin/Component.php
+++ b/core/lib/Drupal/Core/Plugin/Component.php
@@ -1,22 +1,19 @@
 <?php
 
-namespace Drupal\sdc\Plugin;
+namespace Drupal\Core\Plugin;
 
-use Drupal\Core\Plugin\PluginBase;
-use Drupal\sdc\Component\ComponentMetadata;
-use Drupal\sdc\Exception\InvalidComponentException;
+use Drupal\Core\Theme\Component\ComponentMetadata;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
 
 /**
  * Simple value object that contains information about the component.
- *
- * @internal
  */
-final class Component extends PluginBase {
+class Component extends PluginBase {
 
   /**
    * The component's metadata.
    *
-   * @var \Drupal\sdc\Component\ComponentMetadata
+   * @var \Drupal\Core\Theme\Component\ComponentMetadata
    */
   public readonly ComponentMetadata $metadata;
 
@@ -44,7 +41,7 @@ final class Component extends PluginBase {
   /**
    * Component constructor.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function __construct(array $configuration, $plugin_id, $plugin_definition) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
@@ -89,7 +86,7 @@ public function getTemplatePath(): ?string {
   public function getLibraryName(): string {
     $library_id = $this->getPluginId();
     $library_id = str_replace(':', '--', $library_id);
-    return sprintf('sdc/%s', $library_id);
+    return sprintf('core/components.%s', $library_id);
   }
 
 }
diff --git a/core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataDiscovery.php
similarity index 96%
rename from core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataDiscovery.php
rename to core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataDiscovery.php
index 094cc552c7ad..c589840289ed 100644
--- a/core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataDiscovery.php
@@ -1,16 +1,14 @@
 <?php
 
-namespace Drupal\sdc\Plugin\Discovery;
+namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Discovery\YamlDirectoryDiscovery;
 use Drupal\Core\File\FileSystemInterface;
 
 /**
  * Does the actual finding of the directories with metadata files.
- *
- * @internal
  */
-final class DirectoryWithMetadataDiscovery extends YamlDirectoryDiscovery {
+class DirectoryWithMetadataDiscovery extends YamlDirectoryDiscovery {
 
   /**
    * Constructs a DirectoryWithMetadataDiscovery object.
diff --git a/core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php
similarity index 80%
rename from core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php
rename to core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php
index 8c201af3589a..5af50c091812 100644
--- a/core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataPluginDiscovery.php
@@ -1,19 +1,16 @@
 <?php
 
-namespace Drupal\sdc\Plugin\Discovery;
+namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Core\File\FileSystemInterface;
-use Drupal\Core\Plugin\Discovery\YamlDiscovery;
 
 /**
  * Discover directories that contain a specific metadata file.
- *
- * @internal
  */
-final class DirectoryWithMetadataPluginDiscovery extends YamlDiscovery {
+class DirectoryWithMetadataPluginDiscovery extends YamlDiscovery {
 
   /**
-   * Constructs a YamlDirectoryDiscovery object.
+   * Constructs a DirectoryWithMetadataPluginDiscovery object.
    *
    * @param array $directories
    *   An array of directories to scan, keyed by the provider. The value can
diff --git a/core/modules/sdc/src/Plugin/Discovery/RegexRecursiveFilterIterator.php b/core/lib/Drupal/Core/Plugin/Discovery/RegexRecursiveFilterIterator.php
similarity index 86%
rename from core/modules/sdc/src/Plugin/Discovery/RegexRecursiveFilterIterator.php
rename to core/lib/Drupal/Core/Plugin/Discovery/RegexRecursiveFilterIterator.php
index 15c444dbb0bf..1d86e1bba026 100644
--- a/core/modules/sdc/src/Plugin/Discovery/RegexRecursiveFilterIterator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/RegexRecursiveFilterIterator.php
@@ -1,16 +1,14 @@
 <?php
 
-namespace Drupal\sdc\Plugin\Discovery;
+namespace Drupal\Core\Plugin\Discovery;
 
 /**
  * Iterates over files whose names match a regular expression in a directory.
- *
- * @internal
  */
-final class RegexRecursiveFilterIterator extends \RecursiveFilterIterator {
+class RegexRecursiveFilterIterator extends \RecursiveFilterIterator {
 
   /**
-   * RegexDirectoryIterator constructor.
+   * RegexRecursiveFilterIterator constructor.
    *
    * @param \RecursiveIterator $iterator
    *   The iterator.
diff --git a/core/lib/Drupal/Core/Render/Component/Exception/ComponentNotFoundException.php b/core/lib/Drupal/Core/Render/Component/Exception/ComponentNotFoundException.php
new file mode 100644
index 000000000000..7e33e3432aaf
--- /dev/null
+++ b/core/lib/Drupal/Core/Render/Component/Exception/ComponentNotFoundException.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Render\Component\Exception;
+
+/**
+ * Raised when a component cannot be found.
+ */
+class ComponentNotFoundException extends \Exception {
+
+}
diff --git a/core/lib/Drupal/Core/Render/Component/Exception/IncompatibleComponentSchema.php b/core/lib/Drupal/Core/Render/Component/Exception/IncompatibleComponentSchema.php
new file mode 100644
index 000000000000..2ac5bcd622fd
--- /dev/null
+++ b/core/lib/Drupal/Core/Render/Component/Exception/IncompatibleComponentSchema.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Render\Component\Exception;
+
+/**
+ * Custom exception for incompatible schemas.
+ */
+class IncompatibleComponentSchema extends \Exception {
+
+}
diff --git a/core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentDataException.php b/core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentDataException.php
new file mode 100644
index 000000000000..9c02bcbf51e9
--- /dev/null
+++ b/core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentDataException.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Render\Component\Exception;
+
+/**
+ * Raised when a component is rendering with invalid data.
+ */
+class InvalidComponentDataException extends \Exception {
+
+}
diff --git a/core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentException.php b/core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentException.php
new file mode 100644
index 000000000000..ff3d9704ad57
--- /dev/null
+++ b/core/lib/Drupal/Core/Render/Component/Exception/InvalidComponentException.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Render\Component\Exception;
+
+/**
+ * Custom exception for invalid components.
+ */
+class InvalidComponentException extends \Exception {
+
+}
diff --git a/core/lib/Drupal/Core/Render/Element.php b/core/lib/Drupal/Core/Render/Element.php
index 1fd24219c5ca..ae329e8aee5b 100644
--- a/core/lib/Drupal/Core/Render/Element.php
+++ b/core/lib/Drupal/Core/Render/Element.php
@@ -206,4 +206,34 @@ public static function isEmpty(array $elements) {
     return \array_diff(\array_keys($elements), ['#cache', '#weight']) === [];
   }
 
+  /**
+   * Checks if a candidate is a render array.
+   *
+   * @param mixed $candidate
+   *   The candidate.
+   *
+   * @return bool
+   *   TRUE if it's a render array. FALSE otherwise.
+   */
+  public static function isRenderArray($candidate): bool {
+    if (!is_array($candidate)) {
+      return FALSE;
+    }
+    if (empty($candidate)) {
+      return FALSE;
+    }
+    foreach ($candidate as $key => $value) {
+      if (!is_int($key) && $key !== '' && $key[0] === '#') {
+        continue;
+      }
+      if (!is_array($value)) {
+        return FALSE;
+      }
+      if (!static::isRenderArray($value)) {
+        return FALSE;
+      }
+    }
+    return TRUE;
+  }
+
 }
diff --git a/core/modules/sdc/src/Element/ComponentElement.php b/core/lib/Drupal/Core/Render/Element/ComponentElement.php
similarity index 89%
rename from core/modules/sdc/src/Element/ComponentElement.php
rename to core/lib/Drupal/Core/Render/Element/ComponentElement.php
index 946997b1b24b..d91aa7341579 100644
--- a/core/modules/sdc/src/Element/ComponentElement.php
+++ b/core/lib/Drupal/Core/Render/Element/ComponentElement.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\sdc\Element;
+namespace Drupal\Core\Render\Element;
 
 use Drupal\Core\Render\Attribute\RenderElement;
+use Drupal\Core\Render\Element;
 use Drupal\Core\Render\Element\RenderElement as RenderElementBase;
 use Drupal\Core\Security\DoTrustedCallbackTrait;
-use Drupal\sdc\Exception\InvalidComponentDataException;
-use Drupal\sdc\Utilities;
+use Drupal\Core\Render\Component\Exception\InvalidComponentDataException;
 
 /**
  * Provides a Single Directory Component render element.
@@ -39,7 +39,7 @@ class ComponentElement extends RenderElementBase {
   use DoTrustedCallbackTrait;
 
   /**
-   * Expands a sdc into an inline template with an attachment.
+   * Expands a component into an inline template with an attachment.
    *
    * @param array $element
    *   The element to process. See main class documentation for properties.
@@ -47,7 +47,7 @@ class ComponentElement extends RenderElementBase {
    * @return array
    *   The form element.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentDataException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentDataException
    */
   public function preRenderComponent(array $element): array {
     $props = $element['#props'];
@@ -92,7 +92,7 @@ public function preRenderComponent(array $element): array {
    * @return string
    *   The template.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentDataException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentDataException
    *   When slots are not render arrays.
    */
   private function generateComponentTemplate(
@@ -101,7 +101,7 @@ private function generateComponentTemplate(
     array $slots_alter_callbacks,
     array &$context,
   ): string {
-    $template = '{# This template was dynamically generated by sdc #}' . PHP_EOL;
+    $template = '{# This template was dynamically generated by single directory components #}' . PHP_EOL;
     $template .= sprintf('{%% embed \'%s\' %%}', $id);
     $template .= PHP_EOL;
     foreach ($slots as $slot_name => $slot_value) {
@@ -110,7 +110,7 @@ private function generateComponentTemplate(
           "#plain_text" => (string) $slot_value,
         ];
       }
-      if (!Utilities::isRenderArray($slot_value)) {
+      if (!Element::isRenderArray($slot_value)) {
         $message = sprintf(
           'Unable to render component "%s". A render array or a scalar is expected for the slot "%s" when using the render element with the "#slots" property',
           $id,
diff --git a/core/modules/sdc/src/Twig/ComponentNodeVisitor.php b/core/lib/Drupal/Core/Template/ComponentNodeVisitor.php
similarity index 91%
rename from core/modules/sdc/src/Twig/ComponentNodeVisitor.php
rename to core/lib/Drupal/Core/Template/ComponentNodeVisitor.php
index 53fd666ab076..da7a5e85bbfe 100644
--- a/core/modules/sdc/src/Twig/ComponentNodeVisitor.php
+++ b/core/lib/Drupal/Core/Template/ComponentNodeVisitor.php
@@ -2,12 +2,12 @@
 
 declare(strict_types=1);
 
-namespace Drupal\sdc\Twig;
+namespace Drupal\Core\Template;
 
-use Drupal\sdc\ComponentPluginManager;
-use Drupal\sdc\Exception\ComponentNotFoundException;
-use Drupal\sdc\Exception\InvalidComponentException;
-use Drupal\sdc\Plugin\Component;
+use Drupal\Core\Plugin\Component;
+use Drupal\Core\Render\Component\Exception\ComponentNotFoundException;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Twig\Environment;
 use Twig\Node\Expression\ConstantExpression;
 use Twig\Node\Expression\FunctionExpression;
@@ -18,15 +18,13 @@
 
 /**
  * Provides a ComponentNodeVisitor to change the generated parse-tree.
- *
- * @internal
  */
-final class ComponentNodeVisitor implements NodeVisitorInterface {
+class ComponentNodeVisitor implements NodeVisitorInterface {
 
   /**
    * Creates a new ComponentNodeVisitor object.
    *
-   * @param \Drupal\sdc\ComponentPluginManager $pluginManager
+   * @param \Drupal\Core\Theme\ComponentPluginManager $pluginManager
    *   The plugin manager for components.
    */
   public function __construct(protected ComponentPluginManager $pluginManager) {}
@@ -62,12 +60,12 @@ public function leaveNode(Node $node, Environment $env): ?Node {
       $line
     ), $line);
     $print_nodes[] = new PrintNode(new FunctionExpression(
-      'sdc_additional_context',
+      'add_component_context',
       new Node([new ConstantExpression($component_id, $line)]),
       $line
     ), $line);
     $print_nodes[] = new PrintNode(new FunctionExpression(
-      'sdc_validate_props',
+      'validate_component_props',
       new Node([new ConstantExpression($component_id, $line)]),
       $line
     ), $line);
@@ -103,7 +101,7 @@ public function leaveNode(Node $node, Environment $env): ?Node {
    * @param \Twig\Node\Node $node
    *   The node.
    *
-   * @return \Drupal\sdc\Plugin\Component|null
+   * @return \Drupal\Core\Plugin\Component|null
    *   The component, if any.
    */
   protected function getComponent(Node $node): ?Component {
@@ -135,7 +133,7 @@ public function getPriority(): int {
    * undeclared slots. This cheap validation lets us validate during runtime
    * even in production.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    *   When the slots don't pass validation.
    */
   protected function validateSlots(Component $component, Node $node): void {
diff --git a/core/modules/sdc/src/Twig/TwigExtension.php b/core/lib/Drupal/Core/Template/ComponentsTwigExtension.php
similarity index 65%
rename from core/modules/sdc/src/Twig/TwigExtension.php
rename to core/lib/Drupal/Core/Template/ComponentsTwigExtension.php
index 8205080cb05f..b4f5365021b7 100644
--- a/core/modules/sdc/src/Twig/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/ComponentsTwigExtension.php
@@ -1,13 +1,12 @@
 <?php
 
-namespace Drupal\sdc\Twig;
+namespace Drupal\Core\Template;
 
-use Drupal\Core\Template\Attribute;
-use Drupal\sdc\Component\ComponentValidator;
-use Drupal\sdc\ComponentPluginManager;
-use Drupal\sdc\Exception\ComponentNotFoundException;
-use Drupal\sdc\Exception\InvalidComponentException;
-use Drupal\sdc\Plugin\Component;
+use Drupal\Core\Plugin\Component;
+use Drupal\Core\Render\Component\Exception\ComponentNotFoundException;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
+use Drupal\Core\Theme\Component\ComponentValidator;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Twig\Extension\AbstractExtension;
 use Twig\TwigFunction;
 
@@ -16,14 +15,14 @@
  *
  * @internal
  */
-final class TwigExtension extends AbstractExtension {
+final class ComponentsTwigExtension extends AbstractExtension {
 
   /**
    * Creates TwigExtension.
    *
-   * @param \Drupal\sdc\ComponentPluginManager $pluginManager
+   * @param \Drupal\Core\Theme\ComponentPluginManager $pluginManager
    *   The component plugin manager.
-   * @param \Drupal\sdc\Component\ComponentValidator $componentValidator
+   * @param \Drupal\Core\Theme\Component\ComponentValidator $componentValidator
    *   The component validator.
    */
   public function __construct(
@@ -43,16 +42,14 @@ public function getNodeVisitors(): array {
    */
   public function getFunctions(): array {
     return [
-      new TwigFunction(
-        'sdc_additional_context',
-        [$this, 'addAdditionalContext'],
-        ['needs_context' => TRUE]
-      ),
-      new TwigFunction(
-        'sdc_validate_props',
-        [$this, 'validateProps'],
-        ['needs_context' => TRUE]
-      ),
+      new TwigFunction('add_component_context', [$this, 'addAdditionalContext'], ['needs_context' => TRUE]),
+      new TwigFunction('validate_component_props', [$this, 'validateProps'], ['needs_context' => TRUE]),
+      // @todo remove in drupal:11.0.0.
+      // @see https://www.drupal.org/project/drupal/issues/3409456.
+      // Start of BC layer.
+      new TwigFunction('sdc_additional_context', [$this, 'addAdditionalContext'], ['needs_context' => TRUE, 'deprecated' => '10.3.0', 'alternative' => 'add_component_context']),
+      new TwigFunction('sdc_validate_props', [$this, 'validateProps'], ['needs_context' => TRUE, 'deprecated' => '10.3.0', 'alternative' => 'validate_component_props']),
+      // End of BC layer.
     ];
   }
 
@@ -64,7 +61,7 @@ public function getFunctions(): array {
    * @param string $component_id
    *   The component ID.
    *
-   * @throws \Drupal\sdc\Exception\ComponentNotFoundException
+   * @throws \Drupal\Core\Render\Component\Exception\ComponentNotFoundException
    */
   public function addAdditionalContext(array &$context, string $component_id): void {
     $context = $this->mergeAdditionalRenderContext(
@@ -76,7 +73,7 @@ public function addAdditionalContext(array &$context, string $component_id): voi
   /**
    * Calculates additional context for this template.
    *
-   * @param \Drupal\sdc\Plugin\Component $component
+   * @param \Drupal\Core\Plugin\Component $component
    *   The component.
    * @param array $context
    *   The context to update.
@@ -106,7 +103,7 @@ protected function mergeAdditionalRenderContext(Component $component, array $con
    * @param string $component_id
    *   The component ID.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function validateProps(array &$context, string $component_id): void {
     assert($this->doValidateProps($context, $component_id));
@@ -123,7 +120,7 @@ public function validateProps(array &$context, string $component_id): void {
    * @return bool
    *   TRUE if it's valid.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   protected function doValidateProps(array $context, string $component_id): bool {
     try {
diff --git a/core/modules/sdc/src/Twig/TwigComponentLoader.php b/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php
similarity index 91%
rename from core/modules/sdc/src/Twig/TwigComponentLoader.php
rename to core/lib/Drupal/Core/Template/Loader/ComponentLoader.php
index baa069a7584a..2be45eb0abd6 100644
--- a/core/modules/sdc/src/Twig/TwigComponentLoader.php
+++ b/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\sdc\Twig;
+namespace Drupal\Core\Template\Loader;
 
-use Drupal\Core\Utility\Error;
-use Drupal\sdc\ComponentPluginManager;
-use Drupal\sdc\Exception\ComponentNotFoundException;
 use Drupal\Component\Discovery\YamlDirectoryDiscovery;
+use Drupal\Core\Render\Component\Exception\ComponentNotFoundException;
+use Drupal\Core\Theme\ComponentPluginManager;
+use Drupal\Core\Utility\Error;
 use Psr\Log\LoggerInterface;
 use Twig\Error\LoaderError;
 use Twig\Loader\LoaderInterface;
@@ -13,15 +13,13 @@
 
 /**
  * Lets you load templates using the component ID.
- *
- * @internal
  */
-final class TwigComponentLoader implements LoaderInterface {
+class ComponentLoader implements LoaderInterface {
 
   /**
    * Constructs a new ComponentLoader object.
    *
-   * @param \Drupal\sdc\ComponentPluginManager $pluginManager
+   * @param \Drupal\Core\Theme\ComponentPluginManager $pluginManager
    *   The plugin manager.
    * @param \Psr\Log\LoggerInterface $logger
    *   The logger.
@@ -107,7 +105,7 @@ public function getCacheKey($name): string {
       throw new LoaderError('Unable to find component');
     }
     return implode('--', array_filter([
-      'sdc',
+      'components',
       $name,
       $component->getPluginDefinition()['provider'] ?? '',
     ]));
diff --git a/core/modules/sdc/src/Component/ComponentMetadata.php b/core/lib/Drupal/Core/Theme/Component/ComponentMetadata.php
similarity index 94%
rename from core/modules/sdc/src/Component/ComponentMetadata.php
rename to core/lib/Drupal/Core/Theme/Component/ComponentMetadata.php
index 45f394e26ba1..f5c2866bd605 100644
--- a/core/modules/sdc/src/Component/ComponentMetadata.php
+++ b/core/lib/Drupal/Core/Theme/Component/ComponentMetadata.php
@@ -1,17 +1,15 @@
 <?php
 
-namespace Drupal\sdc\Component;
+namespace Drupal\Core\Theme\Component;
 
 use Drupal\Core\Extension\ExtensionLifecycle;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\sdc\Exception\InvalidComponentException;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
 
 /**
  * Component metadata.
- *
- * @internal
  */
-final class ComponentMetadata {
+class ComponentMetadata {
 
   use StringTranslationTrait;
 
@@ -103,7 +101,7 @@ final class ComponentMetadata {
    * @param bool $enforce_schemas
    *   Enforces the definition of schemas for props and slots.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function __construct(array $metadata_info, string $app_root, bool $enforce_schemas) {
     $path = $metadata_info['path'];
@@ -137,7 +135,7 @@ public function __construct(array $metadata_info, string $app_root, bool $enforc
    * @param array $metadata_info
    *   The metadata information as decoded from the component definition file.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   private function parseSchemaInfo(array $metadata_info): void {
     if (empty($metadata_info['props'])) {
diff --git a/core/modules/sdc/src/Component/ComponentValidator.php b/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php
similarity index 94%
rename from core/modules/sdc/src/Component/ComponentValidator.php
rename to core/lib/Drupal/Core/Theme/Component/ComponentValidator.php
index e1d76f6b1da3..41cd4b35bfb2 100644
--- a/core/modules/sdc/src/Component/ComponentValidator.php
+++ b/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php
@@ -1,19 +1,17 @@
 <?php
 
-namespace Drupal\sdc\Component;
+namespace Drupal\Core\Theme\Component;
 
-use Drupal\sdc\Exception\InvalidComponentException;
-use Drupal\sdc\Plugin\Component;
-use Drupal\sdc\Utilities;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
+use Drupal\Core\Render\Element;
+use Drupal\Core\Plugin\Component;
 use JsonSchema\Constraints\Constraint;
 use JsonSchema\Validator;
 
 /**
  * Validates a component based on its definition and the component schema.
- *
- * @internal
  */
-final class ComponentValidator {
+class ComponentValidator {
 
   /**
    * The schema validator.
@@ -52,7 +50,7 @@ public function setValidator(Validator $validator = NULL): void {
    * @return bool
    *   TRUE if the component is valid.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function validateDefinition(array $definition, bool $enforce_schemas): bool {
     // First ensure there are no name collisions between props and slots.
@@ -105,7 +103,7 @@ public function validateDefinition(array $definition, bool $enforce_schemas): bo
     $definition_object = Validator::arrayToObjectRecursive($definition);
     $this->validator->validate(
       $definition_object,
-      (object) ['$ref' => 'file://' . dirname(__DIR__) . '/metadata-full.schema.json']
+      (object) ['$ref' => 'file://' . dirname(__DIR__, 5) . '/assets/schemas/v1/metadata-full.schema.json']
     );
     if (empty($missing_class_errors) && $this->validator->isValid()) {
       return TRUE;
@@ -131,13 +129,13 @@ public function validateDefinition(array $definition, bool $enforce_schemas): bo
    *
    * @param array $context
    *   The Twig context that contains the prop data.
-   * @param \Drupal\sdc\Plugin\Component $component
+   * @param \Drupal\Core\Plugin\Component $component
    *   The component to validate the props against.
    *
    * @return bool
    *   TRUE if the props adhere to the component definition.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function validateProps(array $context, Component $component): bool {
     // If the validator isn't set, then the validation library is not installed.
@@ -181,7 +179,7 @@ function (array $error) use ($context): bool {
         if (($error['constraint'] ?? '') !== 'type') {
           return TRUE;
         }
-        return !Utilities::isRenderArray($context[$error['property']] ?? NULL);
+        return !Element::isRenderArray($context[$error['property']] ?? NULL);
       }
     );
     if (empty($errors)) {
@@ -226,7 +224,7 @@ static function (array $error): string {
    *   Schema. We can do this because we have already validated these props
    *   manually.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   private function validateClassProps(array $props_schema, array $props_raw, string $component_id): array {
     $error_messages = [];
diff --git a/core/modules/sdc/src/Component/SchemaCompatibilityChecker.php b/core/lib/Drupal/Core/Theme/Component/SchemaCompatibilityChecker.php
similarity index 96%
rename from core/modules/sdc/src/Component/SchemaCompatibilityChecker.php
rename to core/lib/Drupal/Core/Theme/Component/SchemaCompatibilityChecker.php
index 0744fd0ef317..9bc36826d34e 100644
--- a/core/modules/sdc/src/Component/SchemaCompatibilityChecker.php
+++ b/core/lib/Drupal/Core/Theme/Component/SchemaCompatibilityChecker.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\sdc\Component;
+namespace Drupal\Core\Theme\Component;
 
-use Drupal\sdc\Exception\IncompatibleComponentSchema;
+use Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema;
 
 /**
  * Checks whether two schemas are compatible.
@@ -11,10 +11,8 @@
  * component if the schemas are not compatible. Component authors must consider
  * their component schema as part of their module/theme API. Breaking changes
  * to the schema must be done in a new major version.
- *
- * @internal
  */
-final class SchemaCompatibilityChecker {
+class SchemaCompatibilityChecker {
 
   /**
    * Checks if the replacement schema is compatible with the old one.
@@ -32,7 +30,7 @@ final class SchemaCompatibilityChecker {
    * @param array $new_schema
    *   The new schema that should be compatible with.
    *
-   * @throws \Drupal\sdc\Exception\IncompatibleComponentSchema
+   * @throws \Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema
    */
   public function isCompatible(array $original_schema, array $new_schema): void {
     $error_messages = [];
diff --git a/core/modules/sdc/src/ComponentNegotiator.php b/core/lib/Drupal/Core/Theme/ComponentNegotiator.php
similarity index 90%
rename from core/modules/sdc/src/ComponentNegotiator.php
rename to core/lib/Drupal/Core/Theme/ComponentNegotiator.php
index 68a8f5500808..43cf466c07f4 100644
--- a/core/modules/sdc/src/ComponentNegotiator.php
+++ b/core/lib/Drupal/Core/Theme/ComponentNegotiator.php
@@ -1,25 +1,14 @@
 <?php
 
-namespace Drupal\sdc;
+namespace Drupal\Core\Theme;
 
 use Drupal\Core\Extension\Extension;
 use Drupal\Core\Extension\ModuleExtensionList;
-use Drupal\Core\Theme\ActiveTheme;
-use Drupal\Core\Theme\ThemeManagerInterface;
 
 /**
  * Determines which component should be used.
- *
- * @internal
  */
-final class ComponentNegotiator {
-
-  /**
-   * The active theme.
-   *
-   * @var \Drupal\Core\Theme\ActiveTheme
-   */
-  protected ActiveTheme $activeTheme;
+class ComponentNegotiator {
 
   /**
    * Holds the component IDs from previous negotiations.
@@ -40,7 +29,6 @@ public function __construct(
     protected ThemeManagerInterface $themeManager,
     protected ModuleExtensionList $moduleExtensionList
   ) {
-    $this->activeTheme = $this->themeManager->getActiveTheme();
   }
 
   /**
@@ -48,7 +36,7 @@ public function __construct(
    *
    * @param string $component_id
    *   The requested component id. Ex: 'my-button', 'my-button--primary',
-   *   'sdc_example:my-button--primary', ...
+   *   'component_example:my-button--primary', ...
    * @param array[] $all_definitions
    *   All the plugin definitions for components keyed by plugin ID.
    *
@@ -71,7 +59,7 @@ public function negotiate(string $component_id, array $all_definitions): ?string
    *
    * @param string $component_id
    *   The requested component id. Ex: 'my-button', 'my-button--primary',
-   *   'sdc_example:my-button--primary', ...
+   *   'component_example:my-button--primary', ...
    * @param array[] $all_definitions
    *   All the plugin definitions for components keyed by plugin ID.
    *
@@ -103,11 +91,11 @@ private function doNegotiate(string $component_id, array $all_definitions): ?str
    */
   private function maybeNegotiateByTheme(array $candidates): ?string {
     // Prepare the error message.
-    $theme_name = $this->activeTheme->getName();
+    $theme_name = $this->themeManager->getActiveTheme()->getName();
     // Let's do theme based negotiation.
     $base_theme_names = array_map(
       static fn(Extension $extension) => $extension->getName(),
-      $this->activeTheme->getBaseThemeExtensions()
+      $this->themeManager->getActiveTheme()->getBaseThemeExtensions()
     );
     $considered_themes = [$theme_name, ...$base_theme_names];
     // Only consider components in the theme hierarchy tree.
@@ -169,9 +157,9 @@ private function maybeNegotiateByModule(array $candidates): ?string {
    */
   private function generateCacheKey(string $component_id): string {
     return sprintf(
-      'sdc-negotiation::%s::%s',
+      'component-negotiation::%s::%s',
       $component_id,
-      $this->activeTheme->getName()
+      $this->themeManager->getActiveTheme()->getName()
     );
   }
 
diff --git a/core/modules/sdc/src/ComponentPluginManager.php b/core/lib/Drupal/Core/Theme/ComponentPluginManager.php
similarity index 88%
rename from core/modules/sdc/src/ComponentPluginManager.php
rename to core/lib/Drupal/Core/Theme/ComponentPluginManager.php
index 6a825febe023..9b33c7af2b93 100644
--- a/core/modules/sdc/src/ComponentPluginManager.php
+++ b/core/lib/Drupal/Core/Theme/ComponentPluginManager.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\sdc;
+namespace Drupal\Core\Theme;
 
 use Drupal\Component\Assertion\Inspector;
 use Drupal\Component\Discovery\YamlDirectoryDiscovery;
@@ -13,25 +13,22 @@
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 use Drupal\Core\Plugin\Factory\ContainerFactory;
-use Drupal\Core\Theme\ThemeManagerInterface;
-use Drupal\sdc\Component\ComponentValidator;
-use Drupal\sdc\Component\SchemaCompatibilityChecker;
-use Drupal\sdc\Exception\ComponentNotFoundException;
-use Drupal\sdc\Exception\IncompatibleComponentSchema;
-use Drupal\sdc\Plugin\Component;
-use Drupal\sdc\Plugin\Discovery\DirectoryWithMetadataPluginDiscovery;
+use Drupal\Core\Theme\Component\ComponentValidator;
+use Drupal\Core\Theme\Component\SchemaCompatibilityChecker;
+use Drupal\Core\Plugin\Component;
+use Drupal\Core\Render\Component\Exception\ComponentNotFoundException;
+use Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema;
+use Drupal\Core\Plugin\Discovery\DirectoryWithMetadataPluginDiscovery;
 
 /**
- * Defines a plugin manager to deal with sdc.
+ * Defines a plugin manager to deal with components.
  *
  * Modules and themes can create components by adding a folder under
- * MODULENAME/components/my-component/my-component.sdc.yml.
+ * MODULENAME/components/my-component/my-component.component.yml.
  *
  * @see plugin_api
- *
- * @internal
  */
-final class ComponentPluginManager extends DefaultPluginManager {
+class ComponentPluginManager extends DefaultPluginManager {
 
   /**
    * {@inheritdoc}
@@ -41,7 +38,7 @@ final class ComponentPluginManager extends DefaultPluginManager {
   ];
 
   /**
-   * Constructs SdcPluginManager object.
+   * Constructs ComponentPluginManager object.
    *
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
@@ -53,13 +50,13 @@ final class ComponentPluginManager extends DefaultPluginManager {
    *   The configuration factory.
    * @param \Drupal\Core\Theme\ThemeManagerInterface $themeManager
    *   The theme manager.
-   * @param \Drupal\sdc\ComponentNegotiator $componentNegotiator
+   * @param \Drupal\Core\Theme\ComponentNegotiator $componentNegotiator
    *   The component negotiator.
    * @param \Drupal\Core\File\FileSystemInterface $fileSystem
    *   The file system service.
-   * @param \Drupal\sdc\Component\SchemaCompatibilityChecker $compatibilityChecker
+   * @param \Drupal\Core\Theme\Component\SchemaCompatibilityChecker $compatibilityChecker
    *   The compatibility checker.
-   * @param \Drupal\sdc\Component\ComponentValidator $componentValidator
+   * @param \Drupal\Core\Theme\Component\ComponentValidator $componentValidator
    *   The component validator.
    * @param string $appRoot
    *   The application root.
@@ -82,8 +79,8 @@ public function __construct(
     // like LinkRelationTypeManager.
     $this->moduleHandler = $module_handler;
     $this->factory = new ContainerFactory($this);
-    $this->setCacheBackend($cacheBackend, 'sdc_plugins');
-    // Note that we are intentionally skipping $this->alterInfo('sdc_info');
+    $this->setCacheBackend($cacheBackend, 'component_plugins');
+    // Note that we are intentionally skipping $this->alterInfo('component_info');
     // We want to ensure that everything related to a component is in the
     // single directory. If the alteration of a component is necessary,
     // component replacement is the preferred tool for that.
@@ -92,7 +89,7 @@ public function __construct(
   /**
    * Creates an instance.
    *
-   * @throws \Drupal\sdc\Exception\ComponentNotFoundException
+   * @throws \Drupal\Core\Render\Component\Exception\ComponentNotFoundException
    *
    * @internal
    */
@@ -128,12 +125,10 @@ public function createInstance($plugin_id, array $configuration = []): Component
    * @param string $component_id
    *   The component ID.
    *
-   * @return \Drupal\sdc\Plugin\Component
+   * @return \Drupal\Core\Plugin\Component
    *   The component.
    *
-   * @throws \Drupal\sdc\Exception\ComponentNotFoundException
-   *
-   * @internal
+   * @throws \Drupal\Core\Render\Component\Exception\ComponentNotFoundException
    */
   public function find(string $component_id): Component {
     $definitions = $this->getDefinitions();
@@ -147,10 +142,8 @@ public function find(string $component_id): Component {
   /**
    * Gets all components.
    *
-   * @return \Drupal\sdc\Plugin\Component[]
+   * @return \Drupal\Core\Plugin\Component[]
    *   An array of Component objects.
-   *
-   * @internal
    */
   public function getAllComponents(): array {
     $plugin_ids = array_keys($this->getDefinitions());
@@ -227,7 +220,7 @@ protected function libraryFromDefinition(array $definition): array {
   protected function getDiscovery(): DirectoryWithMetadataPluginDiscovery {
     if (!isset($this->discovery)) {
       $directories = $this->getScanDirectories();
-      $this->discovery = new DirectoryWithMetadataPluginDiscovery($directories, 'sdc', $this->fileSystem);
+      $this->discovery = new DirectoryWithMetadataPluginDiscovery($directories, 'component', $this->fileSystem);
     }
     return $this->discovery;
   }
@@ -338,7 +331,7 @@ protected function alterDefinition(array $definition): array {
    * @return bool
    *   TRUE if it's valid.
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   private function isValidDefinition(array $definition): bool {
     return $this->componentValidator->validateDefinition(
@@ -441,10 +434,10 @@ private function shouldEnforceSchemas(array $definition): bool {
    * @param string $file_extension
    *   The file extension to detect.
    * @param bool $make_relative
-   *   TRUE to make the filename relative to the SDC module location.
+   *   TRUE to make the filename relative to the core folder.
    *
    * @return string|null
-   *   Filenames, maybe relative to the sdc module.
+   *   Filenames, maybe relative to the core folder.
    */
   private function findAsset(string $component_directory, string $machine_name, string $file_extension, bool $make_relative = FALSE): ?string {
     $absolute_path = sprintf('%s%s%s.%s', $component_directory, DIRECTORY_SEPARATOR, $machine_name, $file_extension);
@@ -460,11 +453,11 @@ private function findAsset(string $component_directory, string $machine_name, st
    * Takes a path and makes it relative to the library provider.
    *
    * Drupal will take a path relative to the library provider in order to put
-   * CSS and JS in the HTML page. The SDC module is the provider for all the
+   * CSS and JS in the HTML page. Core is the provider for all the
    * auto-generated libraries for the components. This means that in order to
    * add <root>/themes/custom/my_theme/components/my-component/my-component.css
-   * in the page, we need to crawl back up from <root>/core/modules/sdc first:
-   * ../../../../themes/custom/my_theme/components/my-component/my-component.css
+   * in the page, we need to crawl back up from <root>/core first:
+   * ../themes/custom/my_theme/components/my-component/my-component.css.
    *
    * @param string $path
    *   The path to the file.
@@ -473,17 +466,12 @@ private function findAsset(string $component_directory, string $machine_name, st
    *   The path relative to the library provider root.
    */
   private function makePathRelativeToLibraryRoot(string $path): string {
-    $library_provider_root = $this->moduleHandler
-      ->getModule('sdc')
-      ->getPath();
-    $num_dots = count(
-      array_filter(explode(DIRECTORY_SEPARATOR, $library_provider_root))
-    );
-    $dots = str_repeat('../', $num_dots);
     $path_from_root = str_starts_with($path, $this->appRoot)
       ? substr($path, strlen($this->appRoot) + 1)
       : $path;
-    return $dots . $path_from_root;
+    // The library owner is in <root>/core, so we need to go one level up to
+    // find the app root.
+    return '../' . $path_from_root;
   }
 
 }
diff --git a/core/modules/sdc/src/ExtensionType.php b/core/lib/Drupal/Core/Theme/ExtensionType.php
similarity index 90%
rename from core/modules/sdc/src/ExtensionType.php
rename to core/lib/Drupal/Core/Theme/ExtensionType.php
index 40ca8f59a8d5..a47bbb1ae3ec 100644
--- a/core/modules/sdc/src/ExtensionType.php
+++ b/core/lib/Drupal/Core/Theme/ExtensionType.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\sdc;
+namespace Drupal\Core\Theme;
 
 /**
  * Enum for supported extension types.
diff --git a/core/modules/sdc/README.txt b/core/modules/sdc/README.txt
index 6029812210c7..fdb7db73186d 100644
--- a/core/modules/sdc/README.txt
+++ b/core/modules/sdc/README.txt
@@ -10,7 +10,7 @@ The API of Single Directory Components includes:
   - The structure of the component metadata (the my-component.component.yml).
     Note that the metadata of the component is described, and optionally
     validated, by the schema in metadata.schema.json (this file is for internal validation and not part of the API).
-  - The render element and its class \Drupal\sdc\Element\ComponentElement.
+  - The render element and its class \Drupal\Core\Render\Element\ComponentElement.
   - The naming convention for the ID when using Twig's include, embed, and
     extends. This naming convention is [module/theme]:[component machine name].
     See the example below.
diff --git a/core/modules/sdc/sdc.info.yml b/core/modules/sdc/sdc.info.yml
index 816437c60994..98ef12cc4312 100644
--- a/core/modules/sdc/sdc.info.yml
+++ b/core/modules/sdc/sdc.info.yml
@@ -3,6 +3,7 @@ type: module
 description: 'Allows discovery and rendering of self-contained UI components.'
 version: VERSION
 package: Core (Experimental)
-lifecycle: experimental
+lifecycle: deprecated
+lifecycle_link: 'https://www.drupal.org/docs/core-modules-and-themes/deprecated-and-obsolete#s-understanding-deprecated-extensions'
 dependencies:
   - drupal:serialization
diff --git a/core/modules/sdc/sdc.module b/core/modules/sdc/sdc.module
index 931de0189d59..89da82a3448a 100644
--- a/core/modules/sdc/sdc.module
+++ b/core/modules/sdc/sdc.module
@@ -5,73 +5,60 @@
  * Module implementation file.
  */
 
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\sdc\Plugin\Component;
-use Drupal\sdc\ComponentPluginManager;
+use Drupal\Core\Theme\ComponentPluginManager;
+use Drupal\Core\Plugin\Component;
 
-/**
- * @file
- * Module implementation file.
- */
-
-// Set class aliases for the classes that will go into core.
-// See the experimental modules policy https://www.drupal.org/core/experimental
-// @todo: remove class aliases in #3354389
-@class_alias('Drupal\sdc\Element\ComponentElement', 'Drupal\Core\Render\Element\ComponentElement');
-@class_alias('Drupal\sdc\Exception\ComponentNotFoundException', 'Drupal\Core\Render\Component\Exception\ComponentNotFoundException');
-@class_alias('Drupal\sdc\Exception\IncompatibleComponentSchema', 'Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema');
-@class_alias('Drupal\sdc\Exception\InvalidComponentDataException', 'Drupal\Core\Render\Component\Exception\InvalidComponentDataException');
-@class_alias('Drupal\sdc\Exception\InvalidComponentException', 'Drupal\Core\Render\Component\Exception\InvalidComponentException');
-
-/**
- * Implements hook_help().
- */
-function sdc_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.sdc':
-      $output = '<h2>' . t('About') . '</h2>';
-      $output .= '<p>' . t('Single Directory Components is a module that aims to simplify the front-end development workflow, and improve maintainability of core and contrib themes. For more information, see the <a href=":docs">online documentation for the Single Directory Components module</a>.', [
-        ':docs' => 'https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components',
-      ]) . '</p>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('General') . '</dt>';
-      $output .= '<dd>' . t('Single Directory Components introduces the concept of UI components to Drupal core. A component is a combination of a Twig template, stylesheets, scripts, assets, and metadata, that live in the same directory. Components represent an encapsulated and re-usable UI element.') . '</dd>';
-      $output .= '<dd>' . t('<a href=":sdc-docs">Single Directory Components</a> reduce the number of framework implementation details required to put templated HTML, CSS, and JS in a Drupal page. They also define explicit component APIs, and provide a methodology to replace a component provided upstream (in a parent theme or module).', [
-        ':sdc-docs' => 'https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components',
-      ]) . '</dd>';
-      $output .= '</dl>';
-
-      return $output;
-  }
-  return NULL;
-}
+@class_alias('Drupal\Core\Render\Element', 'Drupal\sdc\Utilities');
+@class_alias('Drupal\Core\Render\Element\ComponentElement', 'Drupal\sdc\Element\ComponentElement');
+@class_alias('Drupal\Core\Render\Component\Exception\ComponentNotFoundException', 'Drupal\sdc\Exception\ComponentNotFoundException');
+@class_alias('Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema', 'Drupal\sdc\Exception\IncompatibleComponentSchema');
+@class_alias('Drupal\Core\Render\Component\Exception\InvalidComponentDataException', 'Drupal\sdc\Exception\InvalidComponentDataException');
+@class_alias('Drupal\Core\Render\Component\Exception\InvalidComponentException', 'Drupal\sdc\Exception\InvalidComponentException');
+@class_alias('Drupal\Core\Theme\Component\ComponentMetadata', 'Drupal\sdc\Component\ComponentMetadata');
+@class_alias('Drupal\Core\Theme\Component\ComponentValidator', 'Drupal\sdc\Component\ComponentValidator');
+@class_alias('Drupal\Core\Theme\Component\SchemaCompatibilityChecker', 'Drupal\sdc\Component\SchemaCompatibilityChecker');
+@class_alias('Drupal\Core\Plugin\Component', 'Drupal\sdc\Plugin\Component');
+@class_alias('Drupal\Core\Plugin\Discovery\DirectoryWithMetadataDiscovery', 'Drupal\sdc\Plugin\Discovery\DirectoryWithMetadataDiscovery');
+@class_alias('Drupal\Core\Plugin\Discovery\DirectoryWithMetadataPluginDiscovery', 'Drupal\sdc\Plugin\Discovery\DirectoryWithMetadataPluginDiscovery');
+@class_alias('Drupal\Core\Plugin\Discovery\RegexRecursiveFilterIterator', 'Drupal\sdc\Plugin\Discovery\RegexRecursiveFilterIterator');
+@class_alias('Drupal\Core\Template\ComponentNodeVisitor', 'Drupal\sdc\Twig\ComponentNodeVisitor');
+@class_alias('Drupal\Core\Template\Loader\ComponentLoader', 'Drupal\sdc\Twig\TwigComponentLoader');
+@class_alias('Drupal\Core\Theme\ComponentNegotiator', 'Drupal\sdc\ComponentNegotiator');
+@class_alias('Drupal\Core\Theme\ComponentPluginManager', 'Drupal\sdc\ComponentPluginManager');
+@class_alias('Drupal\Core\Theme\ExtensionType', 'Drupal\sdc\ExtensionType');
 
 /**
  * Implements hook_library_info_build().
  */
 function sdc_library_info_build() {
+  $deprecation_message = 'The %library_id% asset library is deprecated in Drupal 10.3.0 and will be removed in Drupal 11.0.0. Use the core/components.[component-id] library instead. See https://www.drupal.org/node/3410260';
   // Iterate over all the components to get the CSS and JS files.
   $plugin_manager = \Drupal::service('plugin.manager.sdc');
   assert($plugin_manager instanceof ComponentPluginManager);
   $components = $plugin_manager->getAllComponents();
+  // Generate backwards compatible deprecated libraries that depend on the new
+  // library name scheme.
   $libraries = array_reduce(
     $components,
-    static function (array $libraries, Component $component) {
-      $library = $component->library;
-      if (empty($library)) {
-        return $libraries;
-      }
+    static function (array $libraries, Component $component) use ($deprecation_message) {
+      // The library name is something like core/components.my-theme--my-comp.
       $library_name = $component->getLibraryName();
-      [, $library_id] = explode('/', $library_name);
-      return array_merge($libraries, [$library_id => $library]);
+      // The library ID is something like my-theme--my-comp.
+      $library_id = str_replace('core/components.', '', $library_name);
+      // Adding these libraries will result in the old 'sdc/my-theme--my-comp'.
+      return array_merge($libraries, [
+        $library_id => [
+          'dependencies' => [$library_name],
+          'deprecated' => $deprecation_message,
+        ],
+      ]);
     },
     []
   );
+  // Alias the library sdc/all to core/components.all.
   $libraries['all'] = [
-    'dependencies' => array_map(
-      static fn(Component $component) => $component->getLibraryName(),
-      $components
-    ),
+    'dependencies' => ['core/components.all'],
+    'deprecated' => 'The %library_id% asset library is deprecated in Drupal 10.3.0 and will be removed in Drupal 11.0.0. Use the core/components.all library instead. See https://www.drupal.org/node/3410260',
   ];
   return $libraries;
 }
diff --git a/core/modules/sdc/sdc.services.yml b/core/modules/sdc/sdc.services.yml
index 519acef6100d..379762e1d793 100644
--- a/core/modules/sdc/sdc.services.yml
+++ b/core/modules/sdc/sdc.services.yml
@@ -2,55 +2,43 @@ services:
   _defaults:
     public: false
 
-  # Twig loader to allow embedding templates with a component identifier.
-  # Note that this service name is not guaranteed to remain the same once this
-  # module is out of the experimental phase.
+  # This service is deprecated, use the one defined in core instead.
   Drupal\sdc\Twig\TwigComponentLoader:
-    arguments:
-      - '@plugin.manager.sdc'
-      - '@logger.channel.default'
-    tags:
-      - { name: twig.loader, priority: 5 }
+    alias: 'Drupal\Core\Template\Loader\ComponentLoader'
+    deprecated:
+      package: 'drupal/core'
+      version: '10.3.0'
+      message: The "%alias_id%" service is deprecated since drupal/core 10.3.0 and will be removed in 11.0.
 
-  # Note that this service name is not guaranteed to remain the same once this
-  # module is out of the experimental phase.
+  # This service is deprecated, use the one defined in core instead.
   Drupal\sdc\ComponentNegotiator:
-    arguments:
-      - '@theme.manager'
-      - '@extension.list.module'
+    alias: 'Drupal\Core\Theme\ComponentNegotiator'
+    deprecated:
+      package: 'drupal/core'
+      version: '10.3.0'
+      message: The "%alias_id%" service is deprecated since drupal/core 10.3.0 and will be removed in 11.0.
 
-  # Note that this service name is not guaranteed to remain the same once this
-  # module is out of the experimental phase.
+  # This service defines the deprecated twig functions related to SDC.
+  # Use the ones defined in core instead.
   Drupal\sdc\Twig\TwigExtension:
-    arguments:
-      - '@plugin.manager.sdc'
-      - '@Drupal\sdc\Component\ComponentValidator'
-    tags:
-      - { name: twig.extension }
+    alias: 'Drupal\Core\Template\ComponentsTwigExtension'
+    deprecated:
+      package: 'drupal/core'
+      version: '10.3.0'
+      message: The "%alias_id%" service is deprecated since drupal/core 10.3.0 and will be removed in 11.0.
 
-  # This service is part of the module's API and it's guaranteed to have the
-  # same name once the module is stable.
-  plugin.manager.sdc:
-    public: true
-    class: Drupal\sdc\ComponentPluginManager
-    arguments:
-      - '@module_handler'
-      - '@theme_handler'
-      - '@cache.discovery'
-      - '@config.factory'
-      - '@theme.manager'
-      - '@Drupal\sdc\ComponentNegotiator'
-      - '@file_system'
-      - '@Drupal\sdc\Component\SchemaCompatibilityChecker'
-      - '@Drupal\sdc\Component\ComponentValidator'
-      - '%app.root%'
+  # This service is deprecated, use the one defined in core instead.
+  Drupal\sdc\Component\SchemaCompatibilityChecker:
+    alias: 'Drupal\Core\Theme\Component\SchemaCompatibilityChecker'
+    deprecated:
+      package: 'drupal/core'
+      version: '10.3.0'
+      message: The "%alias_id%" service is deprecated since drupal/core 10.3.0 and will be removed in 11.0.
 
-  # Note that this service name is not guaranteed to remain the same once this
-  # module is out of the experimental phase.
-  Drupal\sdc\Component\SchemaCompatibilityChecker: {}
-
-  # Note that this service name is not guaranteed to remain the same once this
-  # module is out of the experimental phase.
+  # This service is deprecated, use the one defined in core instead.
   Drupal\sdc\Component\ComponentValidator:
-    calls:
-      - [setValidator, []]
+    alias: 'Drupal\Core\Theme\Component\ComponentValidator'
+    deprecated:
+      package: 'drupal/core'
+      version: '10.3.0'
+      message: The "%alias_id%" service is deprecated since drupal/core 10.3.0 and will be removed in 11.0.
diff --git a/core/modules/sdc/src/Exception/ComponentNotFoundException.php b/core/modules/sdc/src/Exception/ComponentNotFoundException.php
deleted file mode 100644
index 677572cd4f30..000000000000
--- a/core/modules/sdc/src/Exception/ComponentNotFoundException.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\sdc\Exception;
-
-/**
- * Raised when a component cannot be found.
- *
- * @internal
- */
-final class ComponentNotFoundException extends \Exception {
-
-}
diff --git a/core/modules/sdc/src/Exception/IncompatibleComponentSchema.php b/core/modules/sdc/src/Exception/IncompatibleComponentSchema.php
deleted file mode 100644
index d614fabab1bc..000000000000
--- a/core/modules/sdc/src/Exception/IncompatibleComponentSchema.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\sdc\Exception;
-
-/**
- * Custom exception for incompatible schemas.
- *
- * @internal
- */
-final class IncompatibleComponentSchema extends \Exception {
-
-}
diff --git a/core/modules/sdc/src/Exception/InvalidComponentDataException.php b/core/modules/sdc/src/Exception/InvalidComponentDataException.php
deleted file mode 100644
index 971b767d7dec..000000000000
--- a/core/modules/sdc/src/Exception/InvalidComponentDataException.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\sdc\Exception;
-
-/**
- * Raised when a component is rendering with invalid data.
- *
- * @internal
- */
-final class InvalidComponentDataException extends \Exception {
-
-}
diff --git a/core/modules/sdc/src/Exception/InvalidComponentException.php b/core/modules/sdc/src/Exception/InvalidComponentException.php
deleted file mode 100644
index b276b14fc589..000000000000
--- a/core/modules/sdc/src/Exception/InvalidComponentException.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\sdc\Exception;
-
-/**
- * Custom exception for invalid components.
- *
- * @internal
- */
-final class InvalidComponentException extends \Exception {
-
-}
diff --git a/core/modules/sdc/src/Utilities.php b/core/modules/sdc/src/Utilities.php
deleted file mode 100644
index 35010419b81a..000000000000
--- a/core/modules/sdc/src/Utilities.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-namespace Drupal\sdc;
-
-/**
- * Shared utilities for SDC.
- *
- * @internal
- */
-final class Utilities {
-
-  /**
-   * This class should not be instantiated.
-   */
-  private function __construct() {
-  }
-
-  /**
-   * Checks if a candidate is a render array.
-   *
-   * @param mixed $candidate
-   *   The candidate.
-   *
-   * @return bool
-   *   TRUE if it's a render array. FALSE otherwise.
-   *
-   * @todo Move this to the \Drupal\Core\Render\Element class.
-   * @see https://www.drupal.org/i/3352858
-   */
-  public static function isRenderArray($candidate): bool {
-    if (!is_array($candidate)) {
-      return FALSE;
-    }
-    if (empty($candidate)) {
-      return FALSE;
-    }
-    foreach ($candidate as $key => $value) {
-      if (!is_int($key) && $key !== '' && $key[0] === '#') {
-        continue;
-      }
-      if (!is_array($value)) {
-        return FALSE;
-      }
-      if (!static::isRenderArray($value)) {
-        return FALSE;
-      }
-    }
-    return TRUE;
-  }
-
-}
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/no-props/no-props.component.yml b/core/modules/sdc/tests/modules/sdc_test/components/no-props/no-props.component.yml
deleted file mode 100644
index 61c9bcd4de72..000000000000
--- a/core/modules/sdc/tests/modules/sdc_test/components/no-props/no-props.component.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
-name: No props
-description: Component without properties
-props:
-  type: object
-  properties: {}
diff --git a/core/modules/sdc/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml b/core/modules/sdc/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
deleted file mode 100644
index aea87d1e670f..000000000000
--- a/core/modules/sdc/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
-name: Card Without Schema
-status: experimental
diff --git a/core/modules/sdc/tests/src/Functional/GenericTest.php b/core/modules/sdc/tests/src/Functional/GenericTest.php
deleted file mode 100644
index c5740f9f0379..000000000000
--- a/core/modules/sdc/tests/src/Functional/GenericTest.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\Tests\sdc\Functional;
-
-use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
-
-/**
- * Generic module test for sdc.
- *
- * @group sdc
- */
-class GenericTest extends GenericModuleTestBase {}
diff --git a/core/modules/sdc/tests/src/Functional/LibrariesBCLayerTest.php b/core/modules/sdc/tests/src/Functional/LibrariesBCLayerTest.php
new file mode 100644
index 000000000000..e3417be3c89c
--- /dev/null
+++ b/core/modules/sdc/tests/src/Functional/LibrariesBCLayerTest.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\sdc\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the correct rendering of components.
+ *
+ * @group sdc
+ * @group legacy
+ *
+ * @internal
+*/
+final class LibrariesBCLayerTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['system', 'sdc', 'sdc_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'sdc_theme_test';
+
+  /**
+   * Tests libraryOverrides.
+   */
+  public function testLibraryBCLayer(): void {
+    $this->expectDeprecation('The module \'sdc\' is deprecated. See https://www.drupal.org/docs/core-modules-and-themes/deprecated-and-obsolete#s-understanding-deprecated-extensions');
+    $this->expectDeprecation('The sdc/sdc_theme_test--my-card asset library is deprecated in Drupal 10.3.0 and will be removed in Drupal 11.0.0. Use the core/components.[component-id] library instead. See https://www.drupal.org/node/3410260');
+    $build = [
+      '#type' => 'inline_template',
+      '#template' => "<h2>Foo</h2>{{ attach_library('sdc/sdc_theme_test--my-card') }}",
+    ];
+    \Drupal::state()->set('sdc_test_component', $build);
+    $output = $this->drupalGet('sdc-test-component');
+    // Ensure the CSS from the component is properly added to the page.
+    $this->assertStringContainsString('my-card.css', $output);
+  }
+
+}
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentKernelTestBase.php b/core/modules/sdc/tests/src/Kernel/ComponentKernelTestBase.php
deleted file mode 100644
index 4e361d0ce009..000000000000
--- a/core/modules/sdc/tests/src/Kernel/ComponentKernelTestBase.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\Tests\sdc\Kernel;
-
-use Drupal\KernelTests\KernelTestBase;
-use Drupal\sdc\ComponentNegotiator;
-use Drupal\sdc\ComponentPluginManager;
-use Drupal\Tests\sdc\Traits\ComponentRendererTrait;
-
-/**
- * Defines a base class for component kernel tests.
- *
- * @internal
- */
-abstract class ComponentKernelTestBase extends KernelTestBase {
-
-  use ComponentRendererTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = [
-    'sdc',
-    'system',
-    'user',
-    'serialization',
-  ];
-
-  /**
-   * Themes to install.
-   *
-   * @var string[]
-   */
-  protected static $themes = [];
-
-  /**
-   * The component negotiator.
-   *
-   * @return \Drupal\sdc\ComponentNegotiator
-   */
-  protected ComponentNegotiator $negotiator;
-
-  /**
-   * The component plugin manager.
-   *
-   * @var \Drupal\sdc\ComponentPluginManager
-   */
-  protected ComponentPluginManager $manager;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-    if (empty(static::$themes)) {
-      throw new \Exception('You need to set the protected static $themes property on your test class, with the first item being the default theme.');
-    }
-    $this->container->get('theme_installer')->install(static::$themes);
-    $this->installConfig('system');
-
-    $system_theme_config = $this->container->get('config.factory')->getEditable('system.theme');
-    $system_theme_config
-      ->set('default', reset(static::$themes))
-      ->save();
-    $this->negotiator = new ComponentNegotiator(
-      \Drupal::service('theme.manager'),
-      \Drupal::service('extension.list.module'),
-    );
-    $this->manager = \Drupal::service('plugin.manager.sdc');
-  }
-
-}
diff --git a/core/modules/sdc/tests/src/Traits/ComponentRendererTrait.php b/core/modules/sdc/tests/src/Traits/ComponentRendererTrait.php
deleted file mode 100644
index 25eec0e340c0..000000000000
--- a/core/modules/sdc/tests/src/Traits/ComponentRendererTrait.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\Tests\sdc\Traits;
-
-use Drupal\Core\Render\BubbleableMetadata;
-use Drupal\Core\Render\RenderContext;
-use Symfony\Component\DomCrawler\Crawler;
-
-/**
- * Defines a trait for rendering components.
- *
- * @internal
- */
-trait ComponentRendererTrait {
-
-  /**
-   * Renders a component for testing sake.
-   *
-   * @param array $component
-   *   Component render array.
-   * @param \Drupal\Core\Render\BubbleableMetadata|null $metadata
-   *   Bubble metadata.
-   *
-   * @return \Symfony\Component\DomCrawler\Crawler
-   *   Crawler for introspecting the rendered component.
-   */
-  protected function renderComponentRenderArray(array $component, ?BubbleableMetadata $metadata = NULL): Crawler {
-    $component = [
-      '#type' => 'container',
-      '#attributes' => [
-        'id' => 'sdc-wrapper',
-      ],
-      'component' => $component,
-    ];
-    $metadata = $metadata ?: new BubbleableMetadata();
-    $context = new RenderContext();
-    $renderer = \Drupal::service('renderer');
-    $output = $renderer->executeInRenderContext($context, fn () => $renderer->render($component));
-    if (!$context->isEmpty()) {
-      $metadata->addCacheableDependency($context->pop());
-    }
-    return new Crawler((string) $output);
-  }
-
-}
diff --git a/core/modules/sdc/tests/src/Unit/UtilitiesTest.php b/core/modules/sdc/tests/src/Unit/UtilitiesTest.php
deleted file mode 100644
index ce10ba880655..000000000000
--- a/core/modules/sdc/tests/src/Unit/UtilitiesTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\Tests\sdc\Unit;
-
-use Drupal\sdc\Utilities;
-use PHPUnit\Framework\TestCase;
-
-/**
- * Unit tests for the Utilities class.
- *
- * @coversDefaultClass \Drupal\sdc\Utilities
- *
- * @group sdc
- */
-final class UtilitiesTest extends TestCase {
-
-  /**
-   * @covers ::isRenderArray
-   * @dataProvider dataProviderIsRenderArray
-   */
-  public function testIsRenderArray($build, $expected) {
-    $this->assertSame(
-      $expected,
-      Utilities::isRenderArray($build)
-    );
-  }
-
-  public static function dataProviderIsRenderArray() {
-    return [
-      'valid markup render array' => [['#markup' => 'hello world'], TRUE],
-      'invalid "foo" string' => [['foo', '#markup' => 'hello world'], FALSE],
-      'null is not an array' => [NULL, FALSE],
-      'an empty array is not a render array' => [[], FALSE],
-      'funny enough a key with # is valid' => [['#' => TRUE], TRUE],
-      'nested arrays can be valid too' => [['one' => [2 => ['#three' => 'charm!']]], TRUE],
-    ];
-  }
-
-}
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml b/core/modules/sdc/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml
deleted file mode 100644
index aea87d1e670f..000000000000
--- a/core/modules/sdc/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
-name: Card Without Schema
-status: experimental
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml b/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
deleted file mode 100644
index aea87d1e670f..000000000000
--- a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
-name: Card Without Schema
-status: experimental
diff --git a/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml b/core/modules/system/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
similarity index 70%
rename from core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
rename to core/modules/system/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
index ba20067f0534..3038f56af06a 100644
--- a/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
+++ b/core/modules/system/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
@@ -1,5 +1,3 @@
 name: 'Add another node visitor'
 type: module
-dependencies:
-  - sdc:sdc
 package: Testing
diff --git a/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml b/core/modules/system/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml
rename to core/modules/system/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml
diff --git a/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php b/core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php
rename to core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php
diff --git a/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php b/core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php
rename to core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php
diff --git a/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php b/core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php
rename to core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php
diff --git a/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php b/core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php
rename to core/modules/system/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml b/core/modules/system/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml
similarity index 52%
rename from core/modules/sdc/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml
rename to core/modules/system/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml
index 1d70540cde52..fafe2ae3f432 100644
--- a/core/modules/sdc/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml
+++ b/core/modules/system/tests/modules/sdc_test/components/array-to-object/array-to-object.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Array to Object
 props:
   type: object
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/array-to-object/array-to-object.twig b/core/modules/system/tests/modules/sdc_test/components/array-to-object/array-to-object.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/array-to-object/array-to-object.twig
rename to core/modules/system/tests/modules/sdc_test/components/array-to-object/array-to-object.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.component.yml b/core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.component.yml
similarity index 88%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.component.yml
rename to core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.component.yml
index fe38719d72c8..195903e9ee74 100644
--- a/core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.component.yml
+++ b/core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Banner
 description: Banner with title and a CTA link
 libraryOverrides:
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.css b/core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.css
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.css
rename to core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.css
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.twig b/core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-banner/my-banner.twig
rename to core/modules/system/tests/modules/sdc_test/components/my-banner/my-banner.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.component.yml b/core/modules/system/tests/modules/sdc_test/components/my-button/my-button.component.yml
similarity index 82%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.component.yml
rename to core/modules/system/tests/modules/sdc_test/components/my-button/my-button.component.yml
index c68b6b0025f3..65b3c472096b 100644
--- a/core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.component.yml
+++ b/core/modules/system/tests/modules/sdc_test/components/my-button/my-button.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Button
 description: JavaScript enhanced button that tracks the number of times a user clicked it.
 libraryOverrides:
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.css b/core/modules/system/tests/modules/sdc_test/components/my-button/my-button.css
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.css
rename to core/modules/system/tests/modules/sdc_test/components/my-button/my-button.css
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.js b/core/modules/system/tests/modules/sdc_test/components/my-button/my-button.js
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.js
rename to core/modules/system/tests/modules/sdc_test/components/my-button/my-button.js
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.twig b/core/modules/system/tests/modules/sdc_test/components/my-button/my-button.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-button/my-button.twig
rename to core/modules/system/tests/modules/sdc_test/components/my-button/my-button.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.component.yml b/core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.component.yml
similarity index 82%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.component.yml
rename to core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.component.yml
index c9dc85d51fe0..015b3e16319b 100644
--- a/core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.component.yml
+++ b/core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Call to Action
 description: Call to action link.
 props:
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.css b/core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.css
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.css
rename to core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.css
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.js b/core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.js
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.js
rename to core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.js
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.twig b/core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/my-cta/my-cta.twig
rename to core/modules/system/tests/modules/sdc_test/components/my-cta/my-cta.twig
diff --git a/core/modules/system/tests/modules/sdc_test/components/no-props/no-props.component.yml b/core/modules/system/tests/modules/sdc_test/components/no-props/no-props.component.yml
new file mode 100644
index 000000000000..7b33dc1447f0
--- /dev/null
+++ b/core/modules/system/tests/modules/sdc_test/components/no-props/no-props.component.yml
@@ -0,0 +1,6 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
+name: No props
+description: Component without properties
+props:
+  type: object
+  properties: {}
diff --git a/core/modules/sdc/tests/modules/sdc_test/components/no-props/no-props.twig b/core/modules/system/tests/modules/sdc_test/components/no-props/no-props.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/components/no-props/no-props.twig
rename to core/modules/system/tests/modules/sdc_test/components/no-props/no-props.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test/sdc_test.info.yml b/core/modules/system/tests/modules/sdc_test/sdc_test.info.yml
similarity index 67%
rename from core/modules/sdc/tests/modules/sdc_test/sdc_test.info.yml
rename to core/modules/system/tests/modules/sdc_test/sdc_test.info.yml
index 5c282867d459..e03e7bd69c22 100644
--- a/core/modules/sdc/tests/modules/sdc_test/sdc_test.info.yml
+++ b/core/modules/system/tests/modules/sdc_test/sdc_test.info.yml
@@ -1,5 +1,3 @@
 name: 'Components Test'
 type: module
-dependencies:
-  - sdc:sdc
 package: Testing
diff --git a/core/modules/sdc/tests/modules/sdc_test/sdc_test.routing.yml b/core/modules/system/tests/modules/sdc_test/sdc_test.routing.yml
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/sdc_test.routing.yml
rename to core/modules/system/tests/modules/sdc_test/sdc_test.routing.yml
diff --git a/core/modules/sdc/tests/modules/sdc_test/src/Controller/ServerEndpointController.php b/core/modules/system/tests/modules/sdc_test/src/Controller/ServerEndpointController.php
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test/src/Controller/ServerEndpointController.php
rename to core/modules/system/tests/modules/sdc_test/src/Controller/ServerEndpointController.php
diff --git a/core/modules/system/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml b/core/modules/system/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
new file mode 100644
index 000000000000..2859616a3f40
--- /dev/null
+++ b/core/modules/system/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
@@ -0,0 +1,3 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
+name: Card Without Schema
+status: experimental
diff --git a/core/modules/sdc/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.twig b/core/modules/system/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.twig
rename to core/modules/system/tests/modules/sdc_test_invalid/components/my-card-no-schema/my-card-no-schema.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml b/core/modules/system/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml
similarity index 67%
rename from core/modules/sdc/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml
rename to core/modules/system/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml
index 5c282867d459..e03e7bd69c22 100644
--- a/core/modules/sdc/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml
+++ b/core/modules/system/tests/modules/sdc_test_invalid/sdc_test_invalid.info.yml
@@ -1,5 +1,3 @@
 name: 'Components Test'
 type: module
-dependencies:
-  - sdc:sdc
 package: Testing
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml b/core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml
similarity index 82%
rename from core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml
rename to core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml
index 2a97ee5c1b50..b87f1180111e 100644
--- a/core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml
+++ b/core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Button
 replaces: 'sdc_test:my-button'
 description: JavaScript enhanced button that tracks the number of times a user clicked it.
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.css b/core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.css
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.css
rename to core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.css
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.js b/core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.js
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.js
rename to core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.js
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.twig b/core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test_replacements/components/my-button/my-button.twig
rename to core/modules/system/tests/modules/sdc_test_replacements/components/my-button/my-button.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml b/core/modules/system/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml
similarity index 72%
rename from core/modules/sdc/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml
rename to core/modules/system/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml
index 4ac1285fef80..f721cc3e6f60 100644
--- a/core/modules/sdc/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml
+++ b/core/modules/system/tests/modules/sdc_test_replacements/sdc_test_replacements.info.yml
@@ -1,5 +1,3 @@
 name: 'Components Test Replacements'
 type: module
-dependencies:
-  - sdc:sdc
 package: Testing
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml b/core/modules/system/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml
similarity index 60%
rename from core/modules/sdc/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml
rename to core/modules/system/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml
index 1f5613efa0bb..efb13416dc90 100644
--- a/core/modules/sdc/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml
+++ b/core/modules/system/tests/modules/sdc_test_replacements_invalid/components/foo/foo.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Foo
 status: experimental
 replaces: sdc_theme_test:foo
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements_invalid/components/foo/foo.twig b/core/modules/system/tests/modules/sdc_test_replacements_invalid/components/foo/foo.twig
similarity index 100%
rename from core/modules/sdc/tests/modules/sdc_test_replacements_invalid/components/foo/foo.twig
rename to core/modules/system/tests/modules/sdc_test_replacements_invalid/components/foo/foo.twig
diff --git a/core/modules/sdc/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml b/core/modules/system/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml
similarity index 74%
rename from core/modules/sdc/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml
rename to core/modules/system/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml
index e45e3b8c162d..b122930ff29b 100644
--- a/core/modules/sdc/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml
+++ b/core/modules/system/tests/modules/sdc_test_replacements_invalid/sdc_test_replacements_invalid.info.yml
@@ -1,5 +1,3 @@
 name: 'Components Test Replacements (invalid)'
 type: module
-dependencies:
-  - sdc:sdc
 package: Testing
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/bar/bar.component.yml b/core/modules/system/tests/themes/sdc_theme_test/components/bar/bar.component.yml
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/bar/bar.component.yml
rename to core/modules/system/tests/themes/sdc_theme_test/components/bar/bar.component.yml
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/bar/bar.twig b/core/modules/system/tests/themes/sdc_theme_test/components/bar/bar.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/bar/bar.twig
rename to core/modules/system/tests/themes/sdc_theme_test/components/bar/bar.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/another-stylesheet.css b/core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/another-stylesheet.css
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/another-stylesheet.css
rename to core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/another-stylesheet.css
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml b/core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml
similarity index 76%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml
rename to core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml
index 1c2eebd2e3b7..9433f4f3700d 100644
--- a/core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml
+++ b/core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Lib Overrides
 status: stable
 libraryOverrides:
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.css b/core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.css
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.css
rename to core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.css
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.js b/core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.js
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.js
rename to core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.js
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.twig b/core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.twig
rename to core/modules/system/tests/themes/sdc_theme_test/components/lib-overrides/lib-overrides.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml b/core/modules/system/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml
similarity index 55%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml
rename to core/modules/system/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml
index 1fc8b701b93c..37e85fdfa895 100644
--- a/core/modules/sdc/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml
+++ b/core/modules/system/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Foo
 status: experimental
 libraryOverrides:
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.twig b/core/modules/system/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.twig
rename to core/modules/system/tests/themes/sdc_theme_test/components/mismatching-folder-name/foo.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml b/core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml
similarity index 77%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml
rename to core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml
index 64b6ea45be8b..67d3a01657a8 100644
--- a/core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml
+++ b/core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Card
 status: experimental
 props:
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.css b/core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.css
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.css
rename to core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.css
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.twig b/core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/components/my-card/my-card.twig
rename to core/modules/system/tests/themes/sdc_theme_test/components/my-card/my-card.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test/sdc_theme_test.info.yml b/core/modules/system/tests/themes/sdc_theme_test/sdc_theme_test.info.yml
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test/sdc_theme_test.info.yml
rename to core/modules/system/tests/themes/sdc_theme_test/sdc_theme_test.info.yml
diff --git a/core/modules/system/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml b/core/modules/system/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml
new file mode 100644
index 000000000000..2859616a3f40
--- /dev/null
+++ b/core/modules/system/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.component.yml
@@ -0,0 +1,3 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
+name: Card Without Schema
+status: experimental
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.twig b/core/modules/system/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.twig
rename to core/modules/system/tests/themes/sdc_theme_test_base/components/my-card-no-schema/my-card-no-schema.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_base/sdc_theme_test_base.info.yml b/core/modules/system/tests/themes/sdc_theme_test_base/sdc_theme_test_base.info.yml
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_base/sdc_theme_test_base.info.yml
rename to core/modules/system/tests/themes/sdc_theme_test_base/sdc_theme_test_base.info.yml
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml
similarity index 78%
rename from core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml
rename to core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml
index 4b2a101df6da..d586a21349af 100644
--- a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml
+++ b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.component.yml
@@ -1,4 +1,4 @@
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 name: Card
 status: experimental
 replaces: 'sdc_theme_test:my-card'
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.css b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.css
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.css
rename to core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.css
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.twig b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.twig
rename to core/modules/system/tests/themes/sdc_theme_test_enforce_schema/components/my-card/my-card.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/sdc_theme_test_enforce_schema.info.yml b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema/sdc_theme_test_enforce_schema.info.yml
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema/sdc_theme_test_enforce_schema.info.yml
rename to core/modules/system/tests/themes/sdc_theme_test_enforce_schema/sdc_theme_test_enforce_schema.info.yml
diff --git a/core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
new file mode 100644
index 000000000000..2859616a3f40
--- /dev/null
+++ b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.component.yml
@@ -0,0 +1,3 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
+name: Card Without Schema
+status: experimental
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.twig b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.twig
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.twig
rename to core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/components/my-card-no-schema/my-card-no-schema.twig
diff --git a/core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/sdc_theme_test_enforce_schema_invalid.info.yml b/core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/sdc_theme_test_enforce_schema_invalid.info.yml
similarity index 100%
rename from core/modules/sdc/tests/themes/sdc_theme_test_enforce_schema_invalid/sdc_theme_test_enforce_schema_invalid.info.yml
rename to core/modules/system/tests/themes/sdc_theme_test_enforce_schema_invalid/sdc_theme_test_enforce_schema_invalid.info.yml
diff --git a/core/profiles/demo_umami/demo_umami.info.yml b/core/profiles/demo_umami/demo_umami.info.yml
index 731ebf1b85b9..407380d56445 100644
--- a/core/profiles/demo_umami/demo_umami.info.yml
+++ b/core/profiles/demo_umami/demo_umami.info.yml
@@ -29,7 +29,6 @@ install:
   - dynamic_page_cache
   - taxonomy
   - dblog
-  - sdc
   - search
   - shortcut
   - toolbar
diff --git a/core/profiles/demo_umami/themes/umami/components/badge/badge.component.yml b/core/profiles/demo_umami/themes/umami/components/badge/badge.component.yml
index 44fed982416e..1d68092cc07f 100644
--- a/core/profiles/demo_umami/themes/umami/components/badge/badge.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/badge/badge.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Umami Badge
diff --git a/core/profiles/demo_umami/themes/umami/components/banner/banner.component.yml b/core/profiles/demo_umami/themes/umami/components/banner/banner.component.yml
index 698efa5ccb7c..3e2289108efe 100644
--- a/core/profiles/demo_umami/themes/umami/components/banner/banner.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/banner/banner.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Banner
diff --git a/core/profiles/demo_umami/themes/umami/components/branding/branding.component.yml b/core/profiles/demo_umami/themes/umami/components/branding/branding.component.yml
index 1f2203d34973..8ec4f4e752a8 100644
--- a/core/profiles/demo_umami/themes/umami/components/branding/branding.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/branding/branding.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Branding
diff --git a/core/profiles/demo_umami/themes/umami/components/card/card.component.yml b/core/profiles/demo_umami/themes/umami/components/card/card.component.yml
index f9b2d36c90c1..58dbae540082 100644
--- a/core/profiles/demo_umami/themes/umami/components/card/card.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/card/card.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Card
diff --git a/core/profiles/demo_umami/themes/umami/components/disclaimer/disclaimer.component.yml b/core/profiles/demo_umami/themes/umami/components/disclaimer/disclaimer.component.yml
index 95fcd2f2017e..4d676d303103 100644
--- a/core/profiles/demo_umami/themes/umami/components/disclaimer/disclaimer.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/disclaimer/disclaimer.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Disclaimer
diff --git a/core/profiles/demo_umami/themes/umami/components/footer-block/footer-block.component.yml b/core/profiles/demo_umami/themes/umami/components/footer-block/footer-block.component.yml
index 371151941e7e..3bfef5b9f4b3 100644
--- a/core/profiles/demo_umami/themes/umami/components/footer-block/footer-block.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/footer-block/footer-block.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Footer Block
diff --git a/core/profiles/demo_umami/themes/umami/components/header/header.component.yml b/core/profiles/demo_umami/themes/umami/components/header/header.component.yml
index 7fce771f338e..32c1b357b047 100644
--- a/core/profiles/demo_umami/themes/umami/components/header/header.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/header/header.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Umami header
diff --git a/core/profiles/demo_umami/themes/umami/components/read-more/read-more.component.yml b/core/profiles/demo_umami/themes/umami/components/read-more/read-more.component.yml
index e9b016ada3dd..3b004915e4e5 100644
--- a/core/profiles/demo_umami/themes/umami/components/read-more/read-more.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/read-more/read-more.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Read More
diff --git a/core/profiles/demo_umami/themes/umami/components/title/title.component.yml b/core/profiles/demo_umami/themes/umami/components/title/title.component.yml
index fd8d9c912084..df26ee3abf88 100644
--- a/core/profiles/demo_umami/themes/umami/components/title/title.component.yml
+++ b/core/profiles/demo_umami/themes/umami/components/title/title.component.yml
@@ -1,5 +1,5 @@
 # This is so your IDE knows about the syntax for fixes and autocomplete.
-$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
 
 # The human readable name.
 name: Title
diff --git a/core/profiles/demo_umami/themes/umami/umami.info.yml b/core/profiles/demo_umami/themes/umami/umami.info.yml
index 451d07d3a382..441ebdaf763c 100644
--- a/core/profiles/demo_umami/themes/umami/umami.info.yml
+++ b/core/profiles/demo_umami/themes/umami/umami.info.yml
@@ -7,8 +7,6 @@ libraries:
   - umami/classy.base
   - core/normalize
   - umami/global
-dependencies:
-  - drupal:sdc
 
 libraries-override:
   layout_builder/twocol_section:
diff --git a/core/modules/sdc/tests/src/FunctionalJavascript/ComponentRenderTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Components/ComponentRenderTest.php
similarity index 90%
rename from core/modules/sdc/tests/src/FunctionalJavascript/ComponentRenderTest.php
rename to core/tests/Drupal/FunctionalJavascriptTests/Components/ComponentRenderTest.php
index 4d113806caf4..c479411006af 100644
--- a/core/modules/sdc/tests/src/FunctionalJavascript/ComponentRenderTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Components/ComponentRenderTest.php
@@ -2,7 +2,7 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\sdc\FunctionalJavascript;
+namespace Drupal\FunctionalJavascriptTests\Components;
 
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 
@@ -10,15 +10,13 @@
  * Tests the correct rendering of components.
  *
  * @group sdc
- *
- * @internal
  */
-final class ComponentRenderTest extends WebDriverTestBase {
+class ComponentRenderTest extends WebDriverTestBase {
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['sdc', 'sdc_test'];
+  protected static $modules = ['system', 'sdc_test'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Functional/ComponentRenderTest.php b/core/tests/Drupal/FunctionalTests/Components/ComponentRenderTest.php
similarity index 90%
rename from core/modules/sdc/tests/src/Functional/ComponentRenderTest.php
rename to core/tests/Drupal/FunctionalTests/Components/ComponentRenderTest.php
index 2c80bfbacf21..963661a0cc8e 100644
--- a/core/modules/sdc/tests/src/Functional/ComponentRenderTest.php
+++ b/core/tests/Drupal/FunctionalTests/Components/ComponentRenderTest.php
@@ -2,7 +2,7 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\sdc\Functional;
+namespace Drupal\FunctionalTests\Components;
 
 use Drupal\Tests\BrowserTestBase;
 
@@ -10,15 +10,13 @@
  * Tests the correct rendering of components.
  *
  * @group sdc
- *
- * @internal
  */
-final class ComponentRenderTest extends BrowserTestBase {
+class ComponentRenderTest extends BrowserTestBase {
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['sdc', 'sdc_test'];
+  protected static $modules = ['system', 'sdc_test'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentInvalidReplacementTest.php b/core/tests/Drupal/KernelTests/Components/ComponentInvalidReplacementTest.php
similarity index 67%
rename from core/modules/sdc/tests/src/Kernel/ComponentInvalidReplacementTest.php
rename to core/tests/Drupal/KernelTests/Components/ComponentInvalidReplacementTest.php
index 53e07e1ea37f..9d510646f7e8 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentInvalidReplacementTest.php
+++ b/core/tests/Drupal/KernelTests/Components/ComponentInvalidReplacementTest.php
@@ -1,17 +1,16 @@
 <?php
 
-namespace Drupal\Tests\sdc\Kernel;
+namespace Drupal\KernelTests\Components;
 
-use Drupal\sdc\Exception\IncompatibleComponentSchema;
+use Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema;
+use Drupal\Tests\Core\Theme\Component\ComponentKernelTestBase;
 
 /**
  * Tests invalid render options for components.
  *
  * @group sdc
- *
- * @internal
  */
-final class ComponentInvalidReplacementTest extends ComponentKernelTestBase {
+class ComponentInvalidReplacementTest extends ComponentKernelTestBase {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentNodeVisitorTest.php b/core/tests/Drupal/KernelTests/Components/ComponentNodeVisitorTest.php
similarity index 67%
rename from core/modules/sdc/tests/src/Kernel/ComponentNodeVisitorTest.php
rename to core/tests/Drupal/KernelTests/Components/ComponentNodeVisitorTest.php
index ef541d0aa532..2ff8743a2af6 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentNodeVisitorTest.php
+++ b/core/tests/Drupal/KernelTests/Components/ComponentNodeVisitorTest.php
@@ -1,21 +1,21 @@
 <?php
 
-namespace Drupal\Tests\sdc\Kernel;
+namespace Drupal\KernelTests\Components;
+
+use Drupal\Tests\Core\Theme\Component\ComponentKernelTestBase;
 
 /**
  * Tests the node visitor.
  *
- * @coversDefaultClass \Drupal\sdc\Twig\ComponentNodeVisitor
+ * @coversDefaultClass \Drupal\Core\Template\ComponentNodeVisitor
  * @group sdc
- *
- * @internal
  */
-final class ComponentNodeVisitorTest extends ComponentKernelTestBase {
+class ComponentNodeVisitorTest extends ComponentKernelTestBase {
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['sdc', 'sdc_other_node_visitor'];
+  protected static $modules = ['system', 'sdc_other_node_visitor'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentRenderInvalidTest.php b/core/tests/Drupal/KernelTests/Components/ComponentRenderInvalidTest.php
similarity index 87%
rename from core/modules/sdc/tests/src/Kernel/ComponentRenderInvalidTest.php
rename to core/tests/Drupal/KernelTests/Components/ComponentRenderInvalidTest.php
index 6c6c744f2410..fbb5b82569d7 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentRenderInvalidTest.php
+++ b/core/tests/Drupal/KernelTests/Components/ComponentRenderInvalidTest.php
@@ -1,17 +1,16 @@
 <?php
 
-namespace Drupal\Tests\sdc\Kernel;
+namespace Drupal\KernelTests\Components;
 
-use Drupal\sdc\Exception\InvalidComponentException;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
+use Drupal\Tests\Core\Theme\Component\ComponentKernelTestBase;
 
 /**
  * Tests invalid render options for components.
  *
  * @group sdc
- *
- * @internal
  */
-final class ComponentRenderInvalidTest extends ComponentKernelTestBase {
+class ComponentRenderInvalidTest extends ComponentKernelTestBase {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php b/core/tests/Drupal/KernelTests/Components/ComponentRenderTest.php
similarity index 94%
rename from core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
rename to core/tests/Drupal/KernelTests/Components/ComponentRenderTest.php
index f30ad92caada..cc88cdb3e347 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
+++ b/core/tests/Drupal/KernelTests/Components/ComponentRenderTest.php
@@ -1,28 +1,27 @@
 <?php
 
-namespace Drupal\Tests\sdc\Kernel;
+namespace Drupal\KernelTests\Components;
 
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Template\Attribute;
-use Drupal\sdc\ComponentPluginManager;
-use Drupal\sdc\Exception\InvalidComponentDataException;
+use Drupal\Core\Theme\ComponentPluginManager;
+use Drupal\Core\Render\Component\Exception\InvalidComponentDataException;
+use Drupal\Tests\Core\Theme\Component\ComponentKernelTestBase;
 
 /**
  * Tests the correct rendering of components.
  *
  * @group sdc
- *
- * @internal
  */
-final class ComponentRenderTest extends ComponentKernelTestBase {
+class ComponentRenderTest extends ComponentKernelTestBase {
 
   use StringTranslationTrait;
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['sdc', 'sdc_test'];
+  protected static $modules = ['system', 'sdc_test'];
 
   /**
    * {@inheritdoc}
@@ -124,7 +123,7 @@ protected function checkEmbedWithNested(): void {
     ];
     $metadata = new BubbleableMetadata();
     $this->renderComponentRenderArray($build, $metadata);
-    $this->assertEquals(['sdc/sdc_test--my-cta', 'sdc/sdc_test--my-banner'], $metadata->getAttachments()['library']);
+    $this->assertEquals(['core/components.sdc_test--my-cta', 'core/components.sdc_test--my-banner'], $metadata->getAttachments()['library']);
   }
 
   /**
@@ -137,7 +136,7 @@ protected function checkLibraryOverrides(): void {
     ];
     $metadata = new BubbleableMetadata();
     $this->renderComponentRenderArray($build, $metadata);
-    $this->assertEquals(['sdc/sdc_theme_test--lib-overrides'], $metadata->getAttachments()['library']);
+    $this->assertEquals(['core/components.sdc_theme_test--lib-overrides'], $metadata->getAttachments()['library']);
   }
 
   /**
@@ -362,7 +361,7 @@ public function testPluginDefinition(): void {
     assert($plugin_manager instanceof ComponentPluginManager);
     $definition = $plugin_manager->getDefinition('sdc_test:my-banner');
     $this->assertSame('my-banner', $definition['machineName']);
-    $this->assertStringEndsWith('sdc/tests/modules/sdc_test/components/my-banner', $definition['path']);
+    $this->assertStringEndsWith('system/tests/modules/sdc_test/components/my-banner', $definition['path']);
     $this->assertEquals(['core/drupal'], $definition['library']['dependencies']);
     $this->assertNotEmpty($definition['library']['css']['component']);
     $this->assertSame('my-banner.twig', $definition['template']);
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index 3724faaf3f0b..1e92c3da121b 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Extension\ExtensionPathResolver;
 use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
 use Drupal\Core\Theme\ActiveTheme;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\Core\Theme\ThemeManagerInterface;
 use Drupal\Tests\UnitTestCase;
 
@@ -85,6 +86,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
    */
   protected $extensionPathResolver;
 
+  /**
+   * The mocked extension path resolver.
+   *
+   * @var \Drupal\Core\Theme\ComponentPluginManager|\PHPUnit\Framework\MockObject\MockObject
+   */
+  protected $componentPluginManager;
+
   /**
    * {@inheritdoc}
    */
@@ -105,7 +113,8 @@ protected function setUp(): void {
     $this->streamWrapperManager = $this->createMock(StreamWrapperManagerInterface::class);
     $this->librariesDirectoryFileFinder = $this->createMock(LibrariesDirectoryFileFinder::class);
     $this->extensionPathResolver = $this->createMock(ExtensionPathResolver::class);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
+    $this->componentPluginManager = $this->createMock(ComponentPluginManager::class);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver, $this->componentPluginManager);
   }
 
   /**
@@ -121,7 +130,7 @@ public function testBuildByExtensionSimple() {
     FileCacheFactory::setConfiguration([
       'library_parser' => [],
     ]);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver, $this->componentPluginManager);
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
       ->with('example_module')
@@ -655,8 +664,9 @@ public function testLibraryOverride() {
       ->method('getPath')
       ->with('module', 'example_module')
       ->willReturn($path);
+    $this->componentPluginManager = $this->createMock(ComponentPluginManager::class);
 
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver, $this->componentPluginManager);
 
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
@@ -709,7 +719,8 @@ public function testLibraryOverrideDeprecated() {
       ->method('getPath')
       ->with('module', 'deprecated')
       ->willReturn($path);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
+    $this->componentPluginManager = $this->createMock(ComponentPluginManager::class);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver, $this->componentPluginManager);
 
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
diff --git a/core/tests/Drupal/Tests/Core/Extension/GenericTestExistsTest.php b/core/tests/Drupal/Tests/Core/Extension/GenericTestExistsTest.php
index 63696bb5d93c..fb540f943375 100644
--- a/core/tests/Drupal/Tests/Core/Extension/GenericTestExistsTest.php
+++ b/core/tests/Drupal/Tests/Core/Extension/GenericTestExistsTest.php
@@ -19,7 +19,7 @@ class GenericTestExistsTest extends UnitTestCase {
   /**
    * Lists module that do not require a Generic test.
    */
-  protected $modulesNoTest = ['help_topics'];
+  protected $modulesNoTest = ['help_topics', 'sdc'];
 
   /**
    * Tests that the Generic module test exists for all modules.
diff --git a/core/tests/Drupal/Tests/Core/Render/ElementTest.php b/core/tests/Drupal/Tests/Core/Render/ElementTest.php
index 5795e8da7a1b..bc1b0217c6de 100644
--- a/core/tests/Drupal/Tests/Core/Render/ElementTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/ElementTest.php
@@ -225,4 +225,26 @@ public static function providerTestIsEmpty() {
     ];
   }
 
+  /**
+   * @covers ::isRenderArray
+   * @dataProvider dataProviderIsRenderArray
+   */
+  public function testIsRenderArray($build, $expected) {
+    $this->assertSame(
+      $expected,
+      Element::isRenderArray($build)
+    );
+  }
+
+  public function dataProviderIsRenderArray() {
+    return [
+      'valid markup render array' => [['#markup' => 'hello world'], TRUE],
+      'invalid "foo" string' => [['foo', '#markup' => 'hello world'], FALSE],
+      'null is not an array' => [NULL, FALSE],
+      'an empty array is not a render array' => [[], FALSE],
+      'funny enough a key with # is valid' => [['#' => TRUE], TRUE],
+      'nested arrays can be valid too' => [['one' => [2 => ['#three' => 'charm!']]], TRUE],
+    ];
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Theme/Component/ComponentKernelTestBase.php b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentKernelTestBase.php
new file mode 100644
index 000000000000..0c71ae846b9d
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentKernelTestBase.php
@@ -0,0 +1,105 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\Core\Theme\Component;
+
+use Drupal\Core\Render\BubbleableMetadata;
+use Drupal\Core\Render\RenderContext;
+use Drupal\Core\Theme\ComponentNegotiator;
+use Drupal\Core\Theme\ComponentPluginManager;
+use Drupal\KernelTests\KernelTestBase;
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Defines a base class for component kernel tests.
+ */
+abstract class ComponentKernelTestBase extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'system',
+    'user',
+    'serialization',
+  ];
+
+  /**
+   * Themes to install.
+   *
+   * @var string[]
+   */
+  protected static $themes = [];
+
+  /**
+   * The component negotiator.
+   *
+   * @return \Drupal\Core\Theme\ComponentNegotiator
+   */
+  protected ComponentNegotiator $negotiator;
+
+  /**
+   * The component plugin manager.
+   *
+   * @var \Drupal\Core\Theme\ComponentPluginManager
+   */
+  protected ComponentPluginManager $manager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+    if (empty(static::$themes)) {
+      throw new \Exception('You need to set the protected static $themes property on your test class, with the first item being the default theme.');
+    }
+    $this->container->get('theme_installer')->install(static::$themes);
+    $this->installConfig('system');
+
+    $system_theme_config = $this->container->get('config.factory')->getEditable('system.theme');
+    $theme_name = reset(static::$themes);
+    $system_theme_config
+      ->set('default', $theme_name)
+      ->save();
+    $theme_manager = \Drupal::service('theme.manager');
+    $active_theme = \Drupal::service('theme.initialization')->initTheme($theme_name);
+    $theme_manager->setActiveTheme($active_theme);
+
+    $this->negotiator = new ComponentNegotiator(
+      $theme_manager,
+      \Drupal::service('extension.list.module'),
+    );
+    $this->manager = \Drupal::service('plugin.manager.sdc');
+  }
+
+  /**
+   * Renders a component for testing sake.
+   *
+   * @param array $component
+   *   Component render array.
+   * @param \Drupal\Core\Render\BubbleableMetadata|null $metadata
+   *   Bubble metadata.
+   *
+   * @return \Symfony\Component\DomCrawler\Crawler
+   *   Crawler for introspecting the rendered component.
+   */
+  protected function renderComponentRenderArray(array $component, ?BubbleableMetadata $metadata = NULL): Crawler {
+    $component = [
+      '#type' => 'container',
+      '#attributes' => [
+        'id' => 'sdc-wrapper',
+      ],
+      'component' => $component,
+    ];
+    $metadata = $metadata ?: new BubbleableMetadata();
+    $context = new RenderContext();
+    $renderer = \Drupal::service('renderer');
+    $output = $renderer->executeInRenderContext($context, fn () => $renderer->render($component));
+    if (!$context->isEmpty()) {
+      $metadata->addCacheableDependency($context->pop());
+    }
+    return new Crawler((string) $output);
+  }
+
+}
diff --git a/core/modules/sdc/tests/src/Unit/ComponentMetadataTest.php b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentMetadataTest.php
similarity index 89%
rename from core/modules/sdc/tests/src/Unit/ComponentMetadataTest.php
rename to core/tests/Drupal/Tests/Core/Theme/Component/ComponentMetadataTest.php
index d486eda26b6c..8eec15748d4c 100644
--- a/core/modules/sdc/tests/src/Unit/ComponentMetadataTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentMetadataTest.php
@@ -2,21 +2,19 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\sdc\Unit;
+namespace Drupal\Tests\Core\Theme\Component;
 
-use Drupal\sdc\Component\ComponentMetadata;
-use Drupal\sdc\Exception\InvalidComponentException;
+use Drupal\Core\Theme\Component\ComponentMetadata;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
 use Drupal\Tests\UnitTestCaseTest;
 
 /**
  * Unit tests for the component metadata class.
  *
- * @coversDefaultClass \Drupal\sdc\Component\ComponentMetadata
+ * @coversDefaultClass \Drupal\Core\Theme\Component\ComponentMetadata
  * @group sdc
- *
- * @internal
  */
-final class ComponentMetadataTest extends UnitTestCaseTest {
+class ComponentMetadataTest extends UnitTestCaseTest {
 
   /**
    * Tests that the correct data is returned for each property.
@@ -59,7 +57,7 @@ public static function dataProviderMetadata(): array {
       'minimal example without schemas' => [
         [
           'path' => 'foo/bar/component-name',
-          'id' => 'sdc:component-name',
+          'id' => 'core:component-name',
           'name' => 'Component Name',
           'libraryOverrides' => ['dependencies' => ['core/drupal']],
           'group' => 'my-group',
@@ -75,8 +73,8 @@ public static function dataProviderMetadata(): array {
       ],
       'complete example with schema' => [
         [
-          '$schema' => 'https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json',
-          'id' => 'sdc:my-button',
+          '$schema' => 'https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json',
+          'id' => 'core:my-button',
           'machineName' => 'my-button',
           'path' => 'foo/my-other/path',
           'name' => 'Button',
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentNegotiatorTest.php b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentNegotiatorTest.php
similarity index 91%
rename from core/modules/sdc/tests/src/Kernel/ComponentNegotiatorTest.php
rename to core/tests/Drupal/Tests/Core/Theme/Component/ComponentNegotiatorTest.php
index 48028a414fa7..c2f40242ba95 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentNegotiatorTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentNegotiatorTest.php
@@ -1,16 +1,16 @@
 <?php
 
-namespace Drupal\Tests\sdc\Kernel;
+declare(strict_types=1);
+
+namespace Drupal\Tests\Core\Theme\Component;
 
 /**
  * Tests the component negotiator.
  *
- * @coversDefaultClass \Drupal\sdc\ComponentNegotiator
+ * @coversDefaultClass \Drupal\Core\Theme\ComponentNegotiator
  * @group sdc
- *
- * @internal
  */
-final class ComponentNegotiatorTest extends ComponentKernelTestBase {
+class ComponentNegotiatorTest extends ComponentKernelTestBase {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentPluginManagerTest.php
similarity index 83%
rename from core/modules/sdc/tests/src/Kernel/ComponentPluginManagerTest.php
rename to core/tests/Drupal/Tests/Core/Theme/Component/ComponentPluginManagerTest.php
index 231f1bd7719b..f962d50de020 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentPluginManagerTest.php
@@ -1,6 +1,8 @@
 <?php
 
-namespace Drupal\Tests\sdc\Kernel;
+declare(strict_types=1);
+
+namespace Drupal\Tests\Core\Theme\Component;
 
 use Drupal\Core\Render\Component\Exception\ComponentNotFoundException;
 
@@ -8,15 +10,13 @@
  * Tests the component plugin manager.
  *
  * @group sdc
- *
- * @internal
  */
-final class ComponentPluginManagerTest extends ComponentKernelTestBase {
+class ComponentPluginManagerTest extends ComponentKernelTestBase {
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['sdc', 'sdc_test', 'sdc_test_replacements'];
+  protected static $modules = ['system', 'sdc_test', 'sdc_test_replacements'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/sdc/tests/src/Unit/ComponentValidatorTest.php b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentValidatorTest.php
similarity index 89%
rename from core/modules/sdc/tests/src/Unit/ComponentValidatorTest.php
rename to core/tests/Drupal/Tests/Core/Theme/Component/ComponentValidatorTest.php
index ddabdae49e56..7c76a1830558 100644
--- a/core/modules/sdc/tests/src/Unit/ComponentValidatorTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/Component/ComponentValidatorTest.php
@@ -2,31 +2,29 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\sdc\Unit;
+namespace Drupal\Tests\Core\Theme\Component;
 
 use Drupal\Core\Template\Attribute;
-use Drupal\sdc\Component\ComponentValidator;
-use Drupal\sdc\Exception\InvalidComponentException;
-use Drupal\sdc\Plugin\Component;
+use Drupal\Core\Theme\Component\ComponentValidator;
+use Drupal\Core\Render\Component\Exception\InvalidComponentException;
+use Drupal\Core\Plugin\Component;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\Yaml\Yaml;
 
 /**
  * Unit tests for the component validation.
  *
- * @coversDefaultClass \Drupal\sdc\Component\ComponentValidator
+ * @coversDefaultClass \Drupal\Core\Theme\Component\ComponentValidator
  * @group sdc
- *
- * @internal
  */
-final class ComponentValidatorTest extends TestCase {
+class ComponentValidatorTest extends TestCase {
 
   /**
    * Tests that valid component definitions don't cause errors.
    *
    * @dataProvider dataProviderValidateDefinitionValid
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function testValidateDefinitionValid(array $definition): void {
     $component_validator = new ComponentValidator();
@@ -92,7 +90,7 @@ public static function dataProviderValidateDefinitionInvalid(): array {
    *
    * @dataProvider dataProviderValidatePropsValid
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function testValidatePropsValid(array $context, string $component_id, array $definition): void {
     $component = new Component(
@@ -140,7 +138,7 @@ public static function dataProviderValidatePropsValid(): array {
    *
    * @dataProvider dataProviderValidatePropsInvalid
    *
-   * @throws \Drupal\sdc\Exception\InvalidComponentException
+   * @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
    */
   public function testValidatePropsInvalid(array $context, string $component_id, array $definition): void {
     $component = new Component(
@@ -201,7 +199,7 @@ public static function dataProviderValidatePropsInvalid(): array {
   private static function loadComponentDefinitionFromFs(string $component_name): array {
     return array_merge(
       Yaml::parseFile(
-        sprintf('%s/modules/sdc_test/components/%s/%s.component.yml', dirname(__DIR__, 2), $component_name, $component_name),
+        sprintf('%s/modules/system/tests/modules/sdc_test/components/%s/%s.component.yml', dirname(__DIR__, 6), $component_name, $component_name),
       ),
       [
         'machineName' => $component_name,
diff --git a/core/modules/sdc/tests/src/Unit/SchemaCompatibilityCheckerTest.php b/core/tests/Drupal/Tests/Core/Theme/Component/SchemaCompatibilityCheckerTest.php
similarity index 90%
rename from core/modules/sdc/tests/src/Unit/SchemaCompatibilityCheckerTest.php
rename to core/tests/Drupal/Tests/Core/Theme/Component/SchemaCompatibilityCheckerTest.php
index 7f542b209ef6..723819f1ace9 100644
--- a/core/modules/sdc/tests/src/Unit/SchemaCompatibilityCheckerTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/Component/SchemaCompatibilityCheckerTest.php
@@ -2,19 +2,17 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\sdc\Unit;
+namespace Drupal\Tests\Core\Theme\Component;
 
-use Drupal\sdc\Component\SchemaCompatibilityChecker;
-use Drupal\sdc\Exception\IncompatibleComponentSchema;
+use Drupal\Core\Theme\Component\SchemaCompatibilityChecker;
+use Drupal\Core\Render\Component\Exception\IncompatibleComponentSchema;
 use Drupal\Tests\UnitTestCase;
 
 /**
- * @coversDefaultClass \Drupal\sdc\Component\SchemaCompatibilityChecker
+ * @coversDefaultClass \Drupal\Core\Theme\Component\SchemaCompatibilityChecker
  * @group sdc
- *
- * @internal
  */
-final class SchemaCompatibilityCheckerTest extends UnitTestCase {
+class SchemaCompatibilityCheckerTest extends UnitTestCase {
 
   /**
    * The system under test.
-- 
GitLab