diff --git a/.ddev/config.yaml b/.ddev/config.yaml
index cd9069024d9a9b52a0f999b6c055ff2ff5503dcd..e8309b323d8341832897652f20934f16f1fc62ed 100644
--- a/.ddev/config.yaml
+++ b/.ddev/config.yaml
@@ -26,8 +26,6 @@ hooks:
     # see the warning about Node.js Snap for Linux at
     # https://docs.cypress.io/guides/getting-started/installing-cypress.
     - exec: 'test -d node_modules || npm clean-install --foreground-scripts'
-    # Build Experience Builder's JavaScript bundle, if needed.
-    - exec: 'XB_UI_PATH=$DDEV_DOCROOT/modules/contrib/experience_builder/ui; test -d $XB_UI_PATH/dist || ( npm --prefix $XB_UI_PATH install && npm --prefix $XB_UI_PATH run build )'
 web_environment:
   # If CANARY is set, Composer will install dev branches of all dependencies (be sure to
   # run `ddev rebuild` if you change this).
diff --git a/ExperienceBuilderDemo.php b/ExperienceBuilderDemo.php
deleted file mode 120000
index a2499e20748a63cb5e6b54413fa07973237cd01d..0000000000000000000000000000000000000000
--- a/ExperienceBuilderDemo.php
+++ /dev/null
@@ -1 +0,0 @@
-project_template/ExperienceBuilderDemo.php
\ No newline at end of file
diff --git a/project_template/ExperienceBuilderDemo.php b/project_template/ExperienceBuilderDemo.php
deleted file mode 100644
index dce40ccd707cd4c2336cbb0c40e78a0e67fb7f7f..0000000000000000000000000000000000000000
--- a/project_template/ExperienceBuilderDemo.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-use Composer\DependencyResolver\Operation\UpdateOperation;
-use Composer\Installer\PackageEvent;
-use Symfony\Component\Process\Process;
-
-/**
- * Uninstalls Experience Builder whenever Composer attempts to update it.
- *
- * Experience Builder currently has no update path, which means anyone who has
- * it installed in demo mode could theoretically, suddenly break their site if
- * Experience Builder ships a breaking change. To prevent that scenario, this
- * plugin will uninstall Experience Builder and delete all of its data before
- * the Composer package is updated.
- */
-final class ExperienceBuilderDemo {
-
-  /**
-   * Uninstalls Experience Builder before it is updated.
-   *
-   * @param \Composer\Installer\PackageEvent $event
-   *   The event object.
-   */
-  public static function onPackageUpdate(PackageEvent $event): void {
-    $operation = $event->getOperation();
-
-    // We only need to uninstall XB if we're updating it from any version less
-    // than 1.0.0-beta1.
-    if ($operation instanceof UpdateOperation) {
-      $from = $operation->getInitialPackage();
-
-      if ($from->getName() === 'drupal/experience_builder' && version_compare($from->getVersion(), '1.0.0-beta1', '<')) {
-        $config = $event->getComposer()->getConfig();
-        $drush = $config->get('bin-dir') . '/drush';
-        assert(is_executable($drush));
-
-        $run_drush = function(array $command) use ($drush): Process {
-          $process = new Process([$drush, ...$command]);
-          return $process->mustRun();
-        };
-
-        // Ensure that Drupal is installed and has a database connection; otherwise,
-        // there's nothing to do.
-        $output = $run_drush(['core:status', '--field=db-status'])
-          ->getOutput();
-        $output = trim($output);
-        if (empty($output)) {
-          return;
-        }
-        $io = $event->getIO();
-        $io->write('<comment>Uninstalling Experience Builder because it is being updated from an unstable version.</>');
-
-        // Ask Drush if Experience Builder is installed. If it isn't, there's
-        // nothing we need to do.
-        $output = $run_drush(['pm:list', '--type=module', '--field=status', '--filter=experience_builder'])
-          ->getOutput();
-        if (trim($output) === 'Disabled') {
-          return;
-        }
-        // Delete all xb_page entities and uninstall XB.
-        $run_drush(['entity:delete', 'xb_page']);
-        $run_drush(['pm:uninstall', 'experience_builder', '--yes']);
-
-        $project_root = dirname($config->getConfigSource()->getName());
-        $io->write("<bg=blue;fg=white>Successfully uninstalled Experience Builder. You can reinstall the demo by running the following command:\n$drush recipe $project_root/recipes/xb_demo</>");
-      }
-    }
-  }
-
-}
diff --git a/project_template/composer.json b/project_template/composer.json
index 8b69993f8eaab71a18887869c36860a6e2642350..ff61c0a7367f62def3c11354fcc8b58bba360b50 100644
--- a/project_template/composer.json
+++ b/project_template/composer.json
@@ -33,7 +33,6 @@
         "drupal/drupal_cms_project": "^1",
         "drupal/drupal_cms_seo_tools": "^1.0.1",
         "drupal/drupal_cms_starter": "^1.0.1",
-        "drupal/experience_builder": "0.x-dev@dev",
         "drupal/project_browser": "@alpha",
         "drupal/webform": "@beta",
         "drush/drush": "^13"
@@ -84,13 +83,5 @@
                 "  * Get involved with the Drupal community: https://drupal.org/getting-involved"
             ]
         }
-    },
-    "scripts": {
-        "pre-package-update": "ExperienceBuilderDemo::onPackageUpdate"
-    },
-    "autoload": {
-        "classmap": [
-            "ExperienceBuilderDemo.php"
-        ]
     }
 }
diff --git a/project_template/recipes/xb_demo/content/xb_page.yml b/project_template/recipes/xb_demo/content/xb_page.yml
deleted file mode 100644
index 5e989e6d79b496770f960af01d9b6d9e45ff6bc3..0000000000000000000000000000000000000000
--- a/project_template/recipes/xb_demo/content/xb_page.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is scaffolded into XB's `content` directory, which will
-# allow the contributed Default Content module to import it when XB
-# ss installed. This should be moved into the `drupal_cms_starter`
-# recipe when XB is a production dependency of Drupal CMS.
-_meta:
-  version: '1.0'
-  entity_type: xb_page
-  uuid: 20354d7a-e4fe-47af-8ff6-187bca92f3f7
-  default_langcode: en
-default:
-  status:
-    -
-      value: true
-  owner:
-    -
-      target_id: 1
-  title:
-    -
-      value: Experience Builder
-  components:
-    - tree: '{"a548b48d-58a8-4077-aa04-da9405a6f418": []}'
-      props: '{}'
-  path:
-    -
-      alias: /xb-demo
-      langcode: en
-  created:
-    -
-      value: 1735191284
-  revision_translation_affected:
-    -
-      value: true
diff --git a/project_template/recipes/xb_demo/recipe.yml b/project_template/recipes/xb_demo/recipe.yml
deleted file mode 100644
index b4360ba7a1c933d6913d4f4a22c5d4c2be358b5c..0000000000000000000000000000000000000000
--- a/project_template/recipes/xb_demo/recipe.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Experience Builder
-type: Drupal CMS
-description: A read-only demonstration of the next-generation Experience Builder for Drupal.
-install:
-  - experience_builder
-config:
-  import:
-    experience_builder:
-      - image.style.xb_avatar
-  actions:
-    experience_builder.settings:
-      simpleConfigUpdate:
-        demo_mode: true
-    # Disable all components XB generated during installation. Some components
-    # have two- or three-part identifiers, so we need to disable those
-    # separately.
-    experience_builder.component.*.*:
-      disable: []
-    experience_builder.component.*.*.*:
-      disable: []
-    # Re-enable the components provided by Drupal CMS.
-    experience_builder.component.sdc.drupal_cms_olivero.*:
-      enable: []