diff --git a/composer.json b/composer.json
index 90744fd709db02725f3a2ca280809b1c634074dc..a83cfffabeaa4f63195682aa8cbf5a1f1e63155c 100644
--- a/composer.json
+++ b/composer.json
@@ -9,7 +9,7 @@
         "chat": "https://www.drupal.org/node/314178"
     },
     "require": {
-        "composer/installers": "^2.0",
+        "composer/installers": "^2.3",
         "drupal/core": "self.version",
         "drupal/core-project-message": "self.version",
         "drupal/core-vendor-hardening": "self.version"
diff --git a/composer.lock b/composer.lock
index 67100282fbd3c51ee179768ab224b62790151514..2d3b72d6bb8883864e6bd021a747661be4fae685 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "ad0467b38272e8c39c7fe422d212e1df",
+    "content-hash": "63f0b59ba81213ad8f8e124c60a8bb82",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -496,7 +496,7 @@
             "dist": {
                 "type": "path",
                 "url": "core",
-                "reference": "7ef1db8ef53f81722f34bc38512af9c4665d9d72"
+                "reference": "f9821a77ceb47977e9db1cf4cb3364e47f74a66d"
             },
             "require": {
                 "asm89/stack-cors": "^2.1",
@@ -583,6 +583,7 @@
                     "file-mapping": {
                         "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig",
                         "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes",
+                        "[project-root]/recipes/README.txt": "assets/scaffold/files/recipes.README.txt",
                         "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc",
                         "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore",
                         "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json",
diff --git a/composer/Plugin/Scaffold/README.md b/composer/Plugin/Scaffold/README.md
index 1b95e33cc5d7960c0923f05d6d08a7990c69dd2c..789107c6a04d190508f72645fdb501395167c437 100644
--- a/composer/Plugin/Scaffold/README.md
+++ b/composer/Plugin/Scaffold/README.md
@@ -389,7 +389,7 @@ Sample composer.json for a project that relies on packages that use composer-sca
   "name": "my/project",
   "require": {
     "drupal/core-composer-scaffold": "*",
-    "composer/installers": "^2.0",
+    "composer/installers": "^2.3",
     "cweagans/composer-patches": "^1.6.5",
     "drupal/core": "^8.8.x-dev",
     "service-provider/d8-scaffold-files": "^1"
diff --git a/composer/Template/LegacyProject/composer.json b/composer/Template/LegacyProject/composer.json
index 204d1dcba1eb6ec152f3efdd116de2e9f579bdc8..f9273d403d53bd49c150a99a39630922bb709a8d 100644
--- a/composer/Template/LegacyProject/composer.json
+++ b/composer/Template/LegacyProject/composer.json
@@ -15,7 +15,7 @@
         }
     ],
     "require": {
-        "composer/installers": "^2.0",
+        "composer/installers": "^2.3",
         "drupal/core-composer-scaffold": "^11",
         "drupal/core-project-message": "^11",
         "drupal/core-recommended": "^11",
diff --git a/composer/Template/RecommendedProject/composer.json b/composer/Template/RecommendedProject/composer.json
index 0b4926dabfda9080ceb2d992ffbaca187398ff0d..7f16c9183670177d559627a9137590d866708d6b 100644
--- a/composer/Template/RecommendedProject/composer.json
+++ b/composer/Template/RecommendedProject/composer.json
@@ -15,7 +15,7 @@
         }
     ],
     "require": {
-        "composer/installers": "^2.0",
+        "composer/installers": "^2.3",
         "drupal/core-composer-scaffold": "^11",
         "drupal/core-project-message": "^11",
         "drupal/core-recommended": "^11"
@@ -54,7 +54,8 @@
             "drush/Commands/contrib/{$name}": ["type:drupal-drush"],
             "web/modules/custom/{$name}": ["type:drupal-custom-module"],
             "web/profiles/custom/{$name}": ["type:drupal-custom-profile"],
-            "web/themes/custom/{$name}": ["type:drupal-custom-theme"]
+            "web/themes/custom/{$name}": ["type:drupal-custom-theme"],
+            "recipes/{$name}": ["type:drupal-recipe"]
         },
         "drupal-core-project-message": {
             "include-keys": ["homepage", "support"],
diff --git a/core/assets/scaffold/files/recipes.README.txt b/core/assets/scaffold/files/recipes.README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..61573929fcf1818f6c2040dcd6570164ba40ffde
--- /dev/null
+++ b/core/assets/scaffold/files/recipes.README.txt
@@ -0,0 +1,10 @@
+Recipes allow the automation of Drupal module and theme installation and
+configuration.
+
+WHAT TO PLACE IN THIS DIRECTORY?
+--------------------------------
+
+Placing downloaded and custom recipes in this directory separates downloaded and
+custom recipes from Drupal core's recipes. This allows Drupal core to be updated
+without overwriting these files.
+
diff --git a/core/composer.json b/core/composer.json
index a12eb72af42abf856d7ca41f1cc63250a46b979c..ec0bc7a058453087e73d9c952ecc0a2948dd4050 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -125,6 +125,7 @@
             "file-mapping": {
                 "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig",
                 "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes",
+                "[project-root]/recipes/README.txt": "assets/scaffold/files/recipes.README.txt",
                 "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc",
                 "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore",
                 "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json",
diff --git a/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php b/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php
index 62fce914785866bdce95246dd249cbc773e21b7a..86e6f934f2456f34bfcfb7721d4d499c18ce4700 100644
--- a/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php
+++ b/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php
@@ -245,7 +245,9 @@ public function testTemplateCreateProject($project, $package_dir, $docroot_dir):
 
     $installed_composer_json = $this->getWorkspaceDirectory() . '/test_project/composer.json';
     $autoloader = $this->getWorkspaceDirectory() . '/test_project' . $docroot_dir . '/autoload.php';
+    $recipes_dir = $this->getWorkspaceDirectory() . '/test_project/recipes';
     $this->assertFileDoesNotExist($autoloader);
+    $this->assertDirectoryDoesNotExist($recipes_dir);
 
     $this->executeCommand("COMPOSER_HOME=$composer_home COMPOSER_ROOT_VERSION=$simulated_core_version composer create-project --no-ansi $project test_project $simulated_core_version -vvv --repository $repository_path");
     $this->assertCommandSuccessful();
@@ -266,6 +268,8 @@ public function testTemplateCreateProject($project, $package_dir, $docroot_dir):
     // Verify that there is an autoloader. This is written by the scaffold
     // plugin, so its existence assures us that scaffolding happened.
     $this->assertFileExists($autoloader);
+    // Verify recipes directory exists.
+    $this->assertDirectoryExists($recipes_dir);
 
     // Verify that the minimum stability in the installed composer.json file
     // matches the stability of the simulated core version.