diff --git a/src/ActivationInstructionsTrait.php b/src/ActivationInstructionsTrait.php
index ff2683bb17a88eb527eaec59e806984515d8d45a..ac5a57582b98380a92a68be91713af7724f2e16e 100644
--- a/src/ActivationInstructionsTrait.php
+++ b/src/ActivationInstructionsTrait.php
@@ -37,13 +37,20 @@ trait ActivationInstructionsTrait {
    *   The given command, in a format that can be copied and pasted.
    */
   protected function commandBox(string $command, string $action, ?TranslatableMarkup $alt = NULL): string {
-    $alt ??= $this->t('Copy the @action command', ['@action' => $action]);
+    $rows = substr_count($command, "\n") + 1;
+
+    $alt ??= $this->formatPlural(
+      $rows,
+      'Copy the @action command',
+      'Copy the @action commands',
+      ['@action' => $action],
+    );
 
     $icon_url = $this->moduleList->getPath('project_browser') . '/images/copy-icon.svg';
     $icon_url = $this->fileUrlGenerator->generateString($icon_url);
 
     $command_box = '<div class="command-box">';
-    $command_box .= '<input value="' . $command . '" readonly />';
+    $command_box .= '<textarea rows="' . $rows . '" readonly>' . $command . '</textarea>';
     $command_box .= '<button data-copy-command id="' . $action . '-btn">';
     $command_box .= '<img src="' . $icon_url . '" alt="' . $alt . '" />';
     $command_box .= '</button>';
diff --git a/src/ModuleActivator.php b/src/ModuleActivator.php
index e001e9350d2fb4b4ab9f6360b5f05af9985bd727..411f4e4cb58f99f2f913110211ce349d29f3fe98 100644
--- a/src/ModuleActivator.php
+++ b/src/ModuleActivator.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\project_browser;
 
+use Composer\InstalledVersions;
 use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\File\FileUrlGeneratorInterface;
@@ -93,14 +94,19 @@ final class ModuleActivator implements ActivatorInterface {
     ]);
     $commands .= '</p>';
     $commands .= '<p>';
-    $commands .= $this->t('Alternatively, you can use <a href="@url" target="_blank" rel="noreferrer noopener">Drush</a> to install it via the command line:', [
+    $commands .= $this->t('Alternatively, you can use <a href="@url" target="_blank" rel="noreferrer noopener">Drush</a> to install it via the command line.', [
       '@url' => 'https://www.drush.org/latest',
     ]);
     $commands .= '</p>';
-    $commands .= $this->commandBox('drush install ' . $project->machineName, 'install');
-    $commands .= '<p>' . $this->t('If Drush is not installed, this will add the tool to your codebase:') . '</p>';
-    $commands .= $this->commandBox('composer require drush/drush', 'install-drush', $this->t('Copy the install Drush command'));
 
+    $command = '';
+    // Only show the command to install Drush if necessary.
+    if (!in_array('drush/drush', InstalledVersions::getInstalledPackages(), TRUE)) {
+      $command .= "composer require drush/drush\n";
+    }
+    $command .= 'drush install ' . $project->machineName;
+
+    $commands .= $this->commandBox($command, 'install');
     return $commands;
   }
 
diff --git a/src/ProjectBrowser/Project.php b/src/ProjectBrowser/Project.php
index 57d83c74d5267a8668d4df40249215879a24b4fc..301dd60ac444e5d9e059caad6c12344baab90c48 100644
--- a/src/ProjectBrowser/Project.php
+++ b/src/ProjectBrowser/Project.php
@@ -192,7 +192,7 @@ class Project implements \JsonSerializable {
       $commands = $commands->setAbsolute()->toString();
     }
     elseif (is_string($commands)) {
-      $commands = Xss::filter($commands, [...Xss::getAdminTagList(), 'input', 'button']);
+      $commands = Xss::filter($commands, [...Xss::getAdminTagList(), 'textarea', 'button']);
     }
 
     return [
diff --git a/src/RecipeActivator.php b/src/RecipeActivator.php
index 85d940f32316d4f1e5acb743143e6db0bd3ae5ca..deb459a009ceda6c430634bc1cf11c87f93dce9f 100644
--- a/src/RecipeActivator.php
+++ b/src/RecipeActivator.php
@@ -106,7 +106,7 @@ class RecipeActivator implements ActivatorInterface, EventSubscriberInterface {
     $instructions = '<p>' . $this->t('To apply this recipe, run the following command at the command line:') . '</p>';
 
     $command = sprintf(
-      'cd %s && %s/php %s/core/scripts/drupal recipe %s',
+      "cd %s\n%s/php %s/core/scripts/drupal recipe %s",
       $this->appRoot,
       // cspell:ignore BINDIR
       PHP_BINDIR,
diff --git a/sveltejs/css/claro.css b/sveltejs/css/claro.css
index bfbb95b1ce931fb7a5a24acde25269ca3c5c20d8..57f7614defec6b06c5a30473b990c538931fa5b1 100644
--- a/sveltejs/css/claro.css
+++ b/sveltejs/css/claro.css
@@ -1,11 +1,12 @@
 .messages__item a {
   word-break: break-word;
 }
-.project-browser-popup input {
+.project-browser-popup textarea {
   width: 90%;
   color: #fff;
   border: none;
   background-color: #292b32;
+  resize: none;
 }
 .project-browser-popup img {
   display: block;
diff --git a/sveltejs/public/build/bundle.js b/sveltejs/public/build/bundle.js
index a02e401a38171b2ce7c54a58b1c78de9f10f0d15..716ae1595f609b2bce6ade934e8a4e93a1e58c92 100644
Binary files a/sveltejs/public/build/bundle.js and b/sveltejs/public/build/bundle.js differ
diff --git a/sveltejs/public/build/bundle.js.map b/sveltejs/public/build/bundle.js.map
index 824e39092505c97f2c56c6852c77d3739ad2722c..46a61313dd45984c8ad3945b14051e91c978c23a 100644
Binary files a/sveltejs/public/build/bundle.js.map and b/sveltejs/public/build/bundle.js.map differ
diff --git a/sveltejs/src/popup.js b/sveltejs/src/popup.js
index 616ff3163958f52abfe2e27894cc51a4a36e1ccf..2d4ddb1e81e2a4321f0f8cf8c17d6406f4c3fcb9 100644
--- a/sveltejs/src/popup.js
+++ b/sveltejs/src/popup.js
@@ -16,9 +16,9 @@ const enableCopyButtons = () => {
       copyButton.addEventListener('click', (e) => {
         // The copy button must be contained in a div
         const container = e.target.closest('div');
-        // The only <input> within the parent dive should have its value set
+        // The only <textarea> within the parent div should have its value set
         // to the command that should be copied.
-        const input = container.querySelector('input');
+        const input = container.querySelector('textarea');
 
         // Make the input value the selected text
         input.select()
diff --git a/tests/src/FunctionalJavascript/ProjectBrowserUiTest.php b/tests/src/FunctionalJavascript/ProjectBrowserUiTest.php
index fd0ac9f1867f89dfb713531038f5611911b07395..c6dc1d71704aece76763cbe09a802005b4b5cc23 100644
--- a/tests/src/FunctionalJavascript/ProjectBrowserUiTest.php
+++ b/tests/src/FunctionalJavascript/ProjectBrowserUiTest.php
@@ -221,19 +221,20 @@ class ProjectBrowserUiTest extends WebDriverTestBase {
     $this->getSession()->executeScript('navigator.clipboard = true');
     $this->assertTrue($assert_session->waitForText('By Hel Vetica'));
     $this->clickWithWait('#project-browser .project__action_button');
-    $require_command = $assert_session->waitForElement('css', 'input[value="composer require drupal/helvetica"]');
-    $this->assertNotEmpty($require_command);
-    $this->assertTrue($require_command->hasAttribute('readonly'));
-    $install_command = $assert_session->waitForElement('css', 'input[value="drush install helvetica"]');
-    $this->assertNotEmpty($install_command);
-    $this->assertTrue($install_command->hasAttribute('readonly'));
+
+    $command_boxes = $page->waitFor(10, fn ($page) => $page->findAll('css', '.command-box textarea[readonly]'));
+    $this->assertCount(2, $command_boxes);
+
+    // The first textarea should have the command to require the module.
+    $this->assertSame('composer require drupal/helvetica', $command_boxes[0]->getValue());
+    // And the second textarea should have the command to install it.
+    $this->assertStringEndsWith('drush install helvetica', $command_boxes[1]->getValue());
 
     // Tests alt text for copy command image.
     $download_commands = $page->findAll('css', '.command-box img');
-    $this->assertCount(3, $download_commands);
+    $this->assertCount(2, $download_commands);
     $this->assertEquals('Copy the download command', $download_commands[0]->getAttribute('alt'));
-    $this->assertEquals('Copy the install command', $download_commands[1]->getAttribute('alt'));
-    $this->assertEquals('Copy the install Drush command', $download_commands[2]->getAttribute('alt'));
+    $this->assertStringStartsWith('Copy the install command', $download_commands[1]->getAttribute('alt'));
   }
 
   /**
@@ -1067,13 +1068,13 @@ class ProjectBrowserUiTest extends WebDriverTestBase {
     $card = $assert_session->waitForElementVisible('css', '.pb-project:contains("Image media type")');
     $this->assertNotEmpty($card);
     $assert_session->buttonExists('View Commands', $card)->press();
-    $input = $assert_session->waitForElementVisible('css', '.command-box input');
+    $input = $assert_session->waitForElementVisible('css', '.command-box textarea');
     $this->assertNotEmpty($input);
     $command = $input->getValue();
     // A full path to the PHP executable should be in the command.
     $this->assertMatchesRegularExpression('/[^\s]+\/php /', $command);
     $drupal_root = $this->getDrupalRoot();
-    $this->assertStringStartsWith("cd $drupal_root && ", $command);
+    $this->assertStringStartsWith("cd $drupal_root\n", $command);
     $this->assertStringEndsWith("php $drupal_root/core/scripts/drupal recipe $drupal_root/core/recipes/image_media_type", $command);
   }