diff --git a/moderation_note.module b/moderation_note.module
index d5293a7..16b365c 100644
--- a/moderation_note.module
+++ b/moderation_note.module
@@ -5,6 +5,9 @@
  * Contains hook implementations for moderation_note.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\moderation_note\Hook\ModerationNoteHooks;
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
@@ -19,133 +22,33 @@ use Drupal\user\UserInterface;
 /**
  * Implements hook_entity_delete().
  */
+#[LegacyHook]
 function moderation_note_entity_delete(EntityInterface $entity) {
-  if ($entity instanceof ModerationNoteInterface) {
-    // Load and delete all child notes for this parent.
-    $ids = \Drupal::entityQuery('moderation_note')
-      ->accessCheck(FALSE)
-      ->condition('parent', $entity->id())
-      ->execute();
-    $notes = \Drupal::entityTypeManager()->getStorage('moderation_note')->loadMultiple($ids);
-  }
-  else {
-    // Load and delete all associated notes for this entity.
-    $ids = \Drupal::entityQuery('moderation_note')
-      ->accessCheck(FALSE)
-      ->condition('entity_type', $entity->getEntityTypeId())
-      ->condition('entity_id', $entity->id())
-      ->execute();
-    $notes = \Drupal::entityTypeManager()->getStorage('moderation_note')->loadMultiple($ids);
-  }
-  \Drupal::entityTypeManager()->getStorage('moderation_note')->delete($notes);
+  \Drupal::service(ModerationNoteHooks::class)->entityDelete($entity);
 }
 
 /**
  * Implements hook_menu_local_tasks_alter().
  */
+#[LegacyHook]
 function moderation_note_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableDependencyInterface &$cacheability) {
-  /** @var \Drupal\content_moderation\ModerationInformation $information */
-  $information = \Drupal::service('content_moderation.moderation_information');
-
-  // Get the current Entity.
-  foreach (\Drupal::routeMatch()->getParameters() as $parameter) {
-    if ($parameter instanceof EntityInterface && $information->isModeratedEntity($parameter)) {
-      $entity = $parameter;
-      break;
-    }
-  }
-  if (!isset($entity) || $entity->isNew()) {
-    return;
-  }
-  $entity_type = $entity->getEntityTypeId();
-  $entity_id = $entity->id();
-  $link = \Drupal::service('moderation_note.menu_count')
-    ->contentLink($entity_type, $entity_id);
-  $link['#access'] = AccessResult::allowedIfHasPermissions(\Drupal::currentUser(), [
-    'access moderation notes',
-  ]);
-  $link['#attached'] = [
-    'library' => ['moderation_note/main'],
-  ];
-  $data['tabs'][0]['moderation_note.list'] = $link;
-
-  $cacheability->addCacheContexts(['user.permissions']);
-  $cacheability->addCacheTags(["moderation_note:$entity_type:$entity_id"]);
+  \Drupal::service(ModerationNoteHooks::class)->menuLocalTasksAlter($data, $route_name, $cacheability);
 }
 
 /**
  * Implements hook_toolbar_alter().
  */
+#[LegacyHook]
 function moderation_note_toolbar_alter(&$items) {
-  $user = \Drupal::currentUser();
-  $uid = $user->id();
-  if (isset($items['user']) && $user->hasPermission('access moderation notes')) {
-    $link = \Drupal::service('moderation_note.menu_count')
-      ->assignedTo($uid);
-    $link['#cache'] = [
-      'contexts' => ['user'],
-      'tags' => ['moderation_note:user:' . $uid],
-    ];
-
-    $items['user']['tray']['moderation_note'] = $link;
-  }
-
-  return $items;
+  return \Drupal::service(ModerationNoteHooks::class)->toolbarAlter($items);
 }
 
 /**
  * Implements hook_preprocess_HOOK() for field templates.
  */
+#[LegacyHook]
 function moderation_note_preprocess_field(&$variables) {
-  $variables['#cache']['contexts'][] = 'user.permissions';
-
-  $element = $variables['element'];
-  /** @var \Drupal\Core\Entity\EntityInterface $entity */
-  $entity = $element['#object'];
-  /** @var \Drupal\Core\Field\FieldItemList $field_list */
-  $field_list = $element['#items'];
-  $field_definition = $field_list->getFieldDefinition();
-
-  if (!_moderation_note_access($entity)) {
-    return;
-  }
-
-  // Check the field type - we only support text and entity reference revision
-  // fields at this time.
-  $supported_types = [
-    'boolean',
-    'datetime',
-    'entity_reference_revisions',
-    'entity_reference',
-    'list_string',
-    'string_long',
-    'string',
-    'text_long',
-    'text_with_summary',
-    'text',
-  ];
-
-  if (!in_array($field_definition->getType(), $supported_types, TRUE)) {
-    return;
-  }
-  /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
-  $definition = $entity->getFieldDefinition($element['#field_name']);
-  if (!$definition->isComputed()) {
-    $variables['#attached']['library'][] = 'moderation_note/main';
-
-    if (_moderation_note_on_entity($entity)->isAllowed()) {
-      $variables['attributes']['data-moderation-note-can-create'] = TRUE;
-    }
-    $variables['attributes']['data-moderation-note-field-id'] = $entity->getEntityTypeId() . '/' . $entity->id() . '/' . $element['#field_name'] . '/' . $element['#language'] . '/' . $element['#view_mode'];
-    $variables['#cache']['tags'][] = implode(':', [
-      'moderation_note',
-      $entity->getEntityTypeId(),
-      $entity->id(),
-      $element['#field_name'],
-      $element['#language'],
-    ]);
-    _moderation_note_attach_field_notes($variables);
-  }
+  \Drupal::service(ModerationNoteHooks::class)->preprocessField($variables);
 }
 
 /**
@@ -246,36 +149,17 @@ function _moderation_note_access(EntityInterface $entity) {
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function moderation_note_theme() {
-  return [
-    'moderation_note' => [
-      'render element' => 'elements',
-    ],
-    'moderation_note__preview' => [
-      'base hook' => 'moderation_note',
-    ],
-    'mail_moderation_note' => [
-      'variables' => [
-        'note' => '',
-        'quote' => '',
-        'author' => '',
-        'header' => '',
-        'view_link' => NULL,
-        'previous_note' => '',
-        'previous_note_quote' => '',
-        'previous_note_author' => '',
-      ],
-    ],
-  ];
+  return \Drupal::service(ModerationNoteHooks::class)->theme();
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK().
  */
+#[LegacyHook]
 function moderation_note_theme_suggestions_moderation_note(array $variables) {
-  return [
-    'moderation_note__' . $variables['elements']['#view_mode'],
-  ];
+  return \Drupal::service(ModerationNoteHooks::class)->themeSuggestionsModerationNote($variables);
 }
 
 /**
@@ -485,7 +369,7 @@ function moderation_note_moderation_note_insert(ModerationNoteInterface $note) {
  */
 function moderation_note_moderation_note_update(ModerationNoteInterface $note) {
   /** @var \Drupal\moderation_note\ModerationNoteInterface $original */
-  $original = $note->original;
+  $original = DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => $note->getOriginal(), fn() => $note->original);
   /** @var \Drupal\Core\Mail\MailManagerInterface $mail_manager */
   $mail_manager = \Drupal::service('plugin.manager.mail');
   if ($original->getAssignee() !== $note->getAssignee() && $note->getAssignee()) {
@@ -506,120 +390,17 @@ function moderation_note_moderation_note_update(ModerationNoteInterface $note) {
 /**
  * Implements hook_entity_view_mode_info_alter().
  */
+#[LegacyHook]
 function moderation_note_entity_view_mode_info_alter(&$view_modes) {
-  $view_modes['moderation_note']['preview'] = [
-    'id' => 'moderation_note.preview',
-    'label' => 'Preview',
-    'targetEntityType' => 'moderation_note',
-    'cache' => TRUE,
-  ];
+  \Drupal::service(ModerationNoteHooks::class)->entityViewModeInfoAlter($view_modes);
 }
 
 /**
  * Implements hook_mail().
  */
+#[LegacyHook]
 function moderation_note_mail($key, &$message, $params) {
-  if (!\Drupal::config('moderation_note.settings')->get('send_email')) {
-    $message['send'] = FALSE;
-    return;
-  }
-  /** @var \Drupal\moderation_note\ModerationNoteInterface $note */
-  $note = $params['note'];
-  /** @var \Drupal\content_moderation\ModerationInformation $information */
-  $information = \Drupal::service('content_moderation.moderation_information');
-  if ($information->hasPendingRevision($note->getModeratedEntity())) {
-    $rel = 'latest-version';
-  }
-  else {
-    $rel = 'canonical';
-  }
-  $view_url = $note->getModeratedEntity()->toUrl($rel)->setAbsolute();
-  if ($key === 'resolve') {
-    $view_link = [
-      '#type' => 'link',
-      '#title' => t('Click here to view the related content'),
-      '#url' => $view_url,
-    ];
-  }
-  else {
-    $view_link = [
-      '#type' => 'link',
-      '#title' => t('Click here to view this note in context'),
-      '#url' => $note->toUrl(),
-    ];
-  }
-  $options = [
-    'langcode' => $message['langcode'],
-  ];
-
-  $header = 'note';
-  switch ($key) {
-    case 'insert':
-      if ($note->hasParent()) {
-        $message['subject'] = t('Reply on "@label"', [
-          '@label' => $note->getModeratedEntity()->label(),
-        ], $options);
-        $header = t('A new reply has been created on "@label" by @author:', [
-          '@label' => $note->getModeratedEntity()->label(),
-          '@author' => $note->getOwner()->getDisplayName(),
-        ], $options);
-      }
-      else {
-        $message['subject'] = t('Note on "@label"', [
-          '@label' => $note->getModeratedEntity()->label(),
-        ], $options);
-        $header = t('A new note has been created on "@label" by @author:', [
-          '@label' => $note->getModeratedEntity()->label(),
-          '@author' => $note->getOwner()->getDisplayName(),
-        ], $options);
-      }
-      break;
-
-    case 'resolve':
-      $message['subject'] = t('Note resolved on "@label"', [
-        '@label' => $note->getModeratedEntity()->label(),
-      ], $options);
-      $header = t('A note has been resolved on "@label":', [
-        '@label' => $note->getModeratedEntity()->label(),
-      ], $options);
-      break;
-
-    case 're-open':
-      $message['subject'] = t('Note re-opened on "@label"', [
-        '@label' => $note->getModeratedEntity()->label(),
-      ], $options);
-      $header = t('A note has been re-opened on "@label":', [
-        '@label' => $note->getModeratedEntity()->label(),
-      ], $options);
-      break;
-
-    case 'assign':
-      $message['subject'] = t('Note assigned to you on "@label"', [
-        '@label' => $note->getModeratedEntity()->label(),
-      ], $options);
-      $header = t('A note has been assigned to you on "@label":', [
-        '@label' => $note->getModeratedEntity()->label(),
-      ], $options);
-      break;
-  }
-  $body = [
-    '#theme' => 'mail_moderation_note',
-    '#header' => $header,
-    '#note' => $note->getText(),
-    '#author' => $note->getOwner()->getDisplayName(),
-    '#quote' => !$note->hasParent() ? $note->getQuote() : '',
-    '#view_link' => $view_link,
-  ];
-  if ($note->hasParent()) {
-    $parent = $note->getParent();
-    $children = $parent->getChildren();
-    array_pop($children);
-    $previous_note = empty($children) ? $parent : end($children);
-    $body['#previous_note'] = $previous_note->getText();
-    $body['#previous_note_author'] = $previous_note->getOwner()->getDisplayName();
-    $body['#previous_note_quote'] = !$previous_note->hasParent() ? $previous_note->getQuote() : '';
-  }
-  $message['body'][] = \Drupal::service('renderer')->renderRoot($body);
+  \Drupal::service(ModerationNoteHooks::class)->mail($key, $message, $params);
 }
 
 /**
diff --git a/moderation_note.services.yml b/moderation_note.services.yml
index 84ad36b..f56441c 100644
--- a/moderation_note.services.yml
+++ b/moderation_note.services.yml
@@ -4,3 +4,7 @@ services:
     arguments:
       - '@entity_type.manager'
       - '@string_translation'
+
+  Drupal\moderation_note\Hook\ModerationNoteHooks:
+    class: Drupal\moderation_note\Hook\ModerationNoteHooks
+    autowire: true
diff --git a/src/Hook/ModerationNoteHooks.php b/src/Hook/ModerationNoteHooks.php
new file mode 100644
index 0000000..71d2487
--- /dev/null
+++ b/src/Hook/ModerationNoteHooks.php
@@ -0,0 +1,303 @@
+<?php
+
+namespace Drupal\moderation_note\Hook;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
+use Drupal\moderation_note\ModerationNoteInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Hook implementations for moderation_note.
+ */
+class ModerationNoteHooks {
+  use StringTranslationTrait;
+
+  /**
+   * Implements hook_entity_delete().
+   */
+  #[Hook('entity_delete')]
+  public static function entityDelete(EntityInterface $entity) {
+    if ($entity instanceof ModerationNoteInterface) {
+      // Load and delete all child notes for this parent.
+      $ids = \Drupal::entityQuery('moderation_note')->accessCheck(FALSE)->condition('parent', $entity->id())->execute();
+      $notes = \Drupal::entityTypeManager()->getStorage('moderation_note')->loadMultiple($ids);
+    }
+    else {
+      // Load and delete all associated notes for this entity.
+      $ids = \Drupal::entityQuery('moderation_note')->accessCheck(FALSE)->condition('entity_type', $entity->getEntityTypeId())->condition('entity_id', $entity->id())->execute();
+      $notes = \Drupal::entityTypeManager()->getStorage('moderation_note')->loadMultiple($ids);
+    }
+    \Drupal::entityTypeManager()->getStorage('moderation_note')->delete($notes);
+  }
+
+  /**
+   * Implements hook_menu_local_tasks_alter().
+   */
+  #[Hook('menu_local_tasks_alter')]
+  public static function menuLocalTasksAlter(&$data, $route_name, RefinableCacheableDependencyInterface &$cacheability) {
+    /** @var \Drupal\content_moderation\ModerationInformation $information */
+    $information = \Drupal::service('content_moderation.moderation_information');
+    // Get the current Entity.
+    foreach (\Drupal::routeMatch()->getParameters() as $parameter) {
+      if ($parameter instanceof EntityInterface && $information->isModeratedEntity($parameter)) {
+        $entity = $parameter;
+        break;
+      }
+    }
+    if (!isset($entity) || $entity->isNew()) {
+      return;
+    }
+    $entity_type = $entity->getEntityTypeId();
+    $entity_id = $entity->id();
+    $link = \Drupal::service('moderation_note.menu_count')->contentLink($entity_type, $entity_id);
+    $link['#access'] = AccessResult::allowedIfHasPermissions(\Drupal::currentUser(), [
+      'access moderation notes',
+    ]);
+    $link['#attached'] = [
+      'library' => [
+        'moderation_note/main',
+      ],
+    ];
+    $data['tabs'][0]['moderation_note.list'] = $link;
+    $cacheability->addCacheContexts([
+      'user.permissions',
+    ]);
+    $cacheability->addCacheTags([
+      "moderation_note:{$entity_type}:{$entity_id}",
+    ]);
+  }
+
+  /**
+   * Implements hook_toolbar_alter().
+   */
+  #[Hook('toolbar_alter')]
+  public static function toolbarAlter(&$items) {
+    $user = \Drupal::currentUser();
+    $uid = $user->id();
+    if (isset($items['user']) && $user->hasPermission('access moderation notes')) {
+      $link = \Drupal::service('moderation_note.menu_count')->assignedTo($uid);
+      $link['#cache'] = [
+        'contexts' => [
+          'user',
+        ],
+        'tags' => [
+          'moderation_note:user:' . $uid,
+        ],
+      ];
+      $items['user']['tray']['moderation_note'] = $link;
+    }
+    return $items;
+  }
+
+  /**
+   * Implements hook_preprocess_HOOK() for field templates.
+   */
+  #[Hook('preprocess_field')]
+  public static function preprocessField(&$variables) {
+    $variables['#cache']['contexts'][] = 'user.permissions';
+    $element = $variables['element'];
+    /** @var \Drupal\Core\Entity\EntityInterface $entity */
+    $entity = $element['#object'];
+    /** @var \Drupal\Core\Field\FieldItemList $field_list */
+    $field_list = $element['#items'];
+    $field_definition = $field_list->getFieldDefinition();
+    if (!_moderation_note_access($entity)) {
+      return;
+    }
+    // Check the field type - we only support text and entity reference revision
+    // fields at this time.
+    $supported_types = [
+      'boolean',
+      'datetime',
+      'entity_reference_revisions',
+      'entity_reference',
+      'list_string',
+      'string_long',
+      'string',
+      'text_long',
+      'text_with_summary',
+      'text',
+    ];
+    if (!in_array($field_definition->getType(), $supported_types, TRUE)) {
+      return;
+    }
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+    $definition = $entity->getFieldDefinition($element['#field_name']);
+    if (!$definition->isComputed()) {
+      $variables['#attached']['library'][] = 'moderation_note/main';
+      if (_moderation_note_on_entity($entity)->isAllowed()) {
+        $variables['attributes']['data-moderation-note-can-create'] = TRUE;
+      }
+      $variables['attributes']['data-moderation-note-field-id'] = $entity->getEntityTypeId() . '/' . $entity->id() . '/' . $element['#field_name'] . '/' . $element['#language'] . '/' . $element['#view_mode'];
+      $variables['#cache']['tags'][] = implode(':', [
+        'moderation_note',
+        $entity->getEntityTypeId(),
+        $entity->id(),
+        $element['#field_name'],
+        $element['#language'],
+      ]);
+      _moderation_note_attach_field_notes($variables);
+    }
+  }
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public static function theme() {
+    return [
+      'moderation_note' => [
+        'render element' => 'elements',
+      ],
+      'moderation_note__preview' => [
+        'base hook' => 'moderation_note',
+      ],
+      'mail_moderation_note' => [
+        'variables' => [
+          'note' => '',
+          'quote' => '',
+          'author' => '',
+          'header' => '',
+          'view_link' => NULL,
+          'previous_note' => '',
+          'previous_note_quote' => '',
+          'previous_note_author' => '',
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * Implements hook_theme_suggestions_HOOK().
+   */
+  #[Hook('theme_suggestions_moderation_note')]
+  public static function themeSuggestionsModerationNote(array $variables) {
+    return [
+      'moderation_note__' . $variables['elements']['#view_mode'],
+    ];
+  }
+
+  /**
+   * Implements hook_entity_view_mode_info_alter().
+   */
+  #[Hook('entity_view_mode_info_alter')]
+  public static function entityViewModeInfoAlter(&$view_modes) {
+    $view_modes['moderation_note']['preview'] = [
+      'id' => 'moderation_note.preview',
+      'label' => 'Preview',
+      'targetEntityType' => 'moderation_note',
+      'cache' => TRUE,
+    ];
+  }
+
+  /**
+   * Implements hook_mail().
+   */
+  #[Hook('mail')]
+  public function mail($key, &$message, $params) {
+    if (!\Drupal::config('moderation_note.settings')->get('send_email')) {
+      $message['send'] = FALSE;
+      return;
+    }
+    /** @var \Drupal\moderation_note\ModerationNoteInterface $note */
+    $note = $params['note'];
+    /** @var \Drupal\content_moderation\ModerationInformation $information */
+    $information = \Drupal::service('content_moderation.moderation_information');
+    if ($information->hasPendingRevision($note->getModeratedEntity())) {
+      $rel = 'latest-version';
+    }
+    else {
+      $rel = 'canonical';
+    }
+    $view_url = $note->getModeratedEntity()->toUrl($rel)->setAbsolute();
+    if ($key === 'resolve') {
+      $view_link = [
+        '#type' => 'link',
+        '#title' => $this->t('Click here to view the related content'),
+        '#url' => $view_url,
+      ];
+    }
+    else {
+      $view_link = [
+        '#type' => 'link',
+        '#title' => $this->t('Click here to view this note in context'),
+        '#url' => $note->toUrl(),
+      ];
+    }
+    $options = [
+      'langcode' => $message['langcode'],
+    ];
+    $header = 'note';
+    switch ($key) {
+      case 'insert':
+        if ($note->hasParent()) {
+          $message['subject'] = $this->t('Reply on "@label"', [
+            '@label' => $note->getModeratedEntity()->label(),
+          ], $options);
+          $header = $this->t('A new reply has been created on "@label" by @author:', [
+            '@label' => $note->getModeratedEntity()->label(),
+            '@author' => $note->getOwner()->getDisplayName(),
+          ], $options);
+        }
+        else {
+          $message['subject'] = $this->t('Note on "@label"', [
+            '@label' => $note->getModeratedEntity()->label(),
+          ], $options);
+          $header = $this->t('A new note has been created on "@label" by @author:', [
+            '@label' => $note->getModeratedEntity()->label(),
+            '@author' => $note->getOwner()->getDisplayName(),
+          ], $options);
+        }
+        break;
+
+      case 'resolve':
+        $message['subject'] = $this->t('Note resolved on "@label"', [
+          '@label' => $note->getModeratedEntity()->label(),
+        ], $options);
+        $header = $this->t('A note has been resolved on "@label":', [
+          '@label' => $note->getModeratedEntity()->label(),
+        ], $options);
+        break;
+
+      case 're-open':
+        $message['subject'] = $this->t('Note re-opened on "@label"', [
+          '@label' => $note->getModeratedEntity()->label(),
+        ], $options);
+        $header = $this->t('A note has been re-opened on "@label":', [
+          '@label' => $note->getModeratedEntity()->label(),
+        ], $options);
+        break;
+
+      case 'assign':
+        $message['subject'] = $this->t('Note assigned to you on "@label"', [
+          '@label' => $note->getModeratedEntity()->label(),
+        ], $options);
+        $header = $this->t('A note has been assigned to you on "@label":', [
+          '@label' => $note->getModeratedEntity()->label(),
+        ], $options);
+        break;
+    }
+    $body = [
+      '#theme' => 'mail_moderation_note',
+      '#header' => $header,
+      '#note' => $note->getText(),
+      '#author' => $note->getOwner()->getDisplayName(),
+      '#quote' => !$note->hasParent() ? $note->getQuote() : '',
+      '#view_link' => $view_link,
+    ];
+    if ($note->hasParent()) {
+      $parent = $note->getParent();
+      $children = $parent->getChildren();
+      array_pop($children);
+      $previous_note = empty($children) ? $parent : end($children);
+      $body['#previous_note'] = $previous_note->getText();
+      $body['#previous_note_author'] = $previous_note->getOwner()->getDisplayName();
+      $body['#previous_note_quote'] = !$previous_note->hasParent() ? $previous_note->getQuote() : '';
+    }
+    $message['body'][] = \Drupal::service('renderer')->renderRoot($body);
+  }
+
+}
diff --git a/tests/src/Functional/ModerationNoteMailTest.php b/tests/src/Functional/ModerationNoteMailTest.php
index 1181652..79b4e3f 100644
--- a/tests/src/Functional/ModerationNoteMailTest.php
+++ b/tests/src/Functional/ModerationNoteMailTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\moderation_note\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Core\Test\AssertMailTrait;
 use Drupal\moderation_note\Entity\ModerationNote;
@@ -14,6 +16,8 @@ use Drupal\Tests\BrowserTestBase;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
+#[RunTestsInSeparateProcesses]
 class ModerationNoteMailTest extends BrowserTestBase {
 
   use AssertMailTrait;
diff --git a/tests/src/FunctionalJavascript/ModerationNoteTest.php b/tests/src/FunctionalJavascript/ModerationNoteTest.php
index 3da470f..b1886f3 100644
--- a/tests/src/FunctionalJavascript/ModerationNoteTest.php
+++ b/tests/src/FunctionalJavascript/ModerationNoteTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\moderation_note\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
@@ -13,6 +15,8 @@ use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
+#[RunTestsInSeparateProcesses]
 class ModerationNoteTest extends WebDriverTestBase {
 
   use ContentModerationTestTrait;
diff --git a/tests/src/Kernel/ModerationNoteEntityTest.php b/tests/src/Kernel/ModerationNoteEntityTest.php
index 5e6227e..369cdb8 100644
--- a/tests/src/Kernel/ModerationNoteEntityTest.php
+++ b/tests/src/Kernel/ModerationNoteEntityTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\moderation_note\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
 use Drupal\moderation_note\Entity\ModerationNote;
 use Drupal\node\Entity\Node;
@@ -13,6 +15,8 @@ use Drupal\user\RoleInterface;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
+#[RunTestsInSeparateProcesses]
 class ModerationNoteEntityTest extends EntityKernelTestBase {
 
   /**
diff --git a/tests/src/Unit/AccessControlHandlerTest.php b/tests/src/Unit/AccessControlHandlerTest.php
index 6c1c08d..bc7e966 100644
--- a/tests/src/Unit/AccessControlHandlerTest.php
+++ b/tests/src/Unit/AccessControlHandlerTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\Entity\EntityInterface;
@@ -20,6 +21,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
  * @coversDefaultClass \Drupal\moderation_note\AccessControlHandler
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class AccessControlHandlerTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/Controller/ModerationNoteControllerTest.php b/tests/src/Unit/Controller/ModerationNoteControllerTest.php
index a057d71..e9028e7 100644
--- a/tests/src/Unit/Controller/ModerationNoteControllerTest.php
+++ b/tests/src/Unit/Controller/ModerationNoteControllerTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit\Controller;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\Entity\EntityFormBuilderInterface;
@@ -27,6 +28,7 @@ use Symfony\Component\HttpFoundation\Request;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class ModerationNoteControllerTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/Form/ModerationNoteFormTest.php b/tests/src/Unit/Form/ModerationNoteFormTest.php
index 8dcea78..e16c807 100644
--- a/tests/src/Unit/Form/ModerationNoteFormTest.php
+++ b/tests/src/Unit/Form/ModerationNoteFormTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit\Form;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
@@ -25,6 +26,7 @@ use Drupal\Tests\UnitTestCase;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class ModerationNoteFormTest extends UnitTestCase {
 
   use StringTranslationTrait;
diff --git a/tests/src/Unit/Form/ModerationNoteResolveFormTest.php b/tests/src/Unit/Form/ModerationNoteResolveFormTest.php
index b14b5f9..da5d3b2 100644
--- a/tests/src/Unit/Form/ModerationNoteResolveFormTest.php
+++ b/tests/src/Unit/Form/ModerationNoteResolveFormTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit\Form;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Entity\EntityRepositoryInterface;
@@ -23,6 +24,7 @@ use Drupal\Tests\UnitTestCase;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class ModerationNoteResolveFormTest extends UnitTestCase {
 
   use StringTranslationTrait;
diff --git a/tests/src/Unit/InstallTest.php b/tests/src/Unit/InstallTest.php
index 703963b..2a56aca 100644
--- a/tests/src/Unit/InstallTest.php
+++ b/tests/src/Unit/InstallTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\moderation_note\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 
@@ -12,6 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class InstallTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/ModerationNoteMenuLocalTasksAlterTest.php b/tests/src/Unit/ModerationNoteMenuLocalTasksAlterTest.php
index 124f95a..b92d57d 100644
--- a/tests/src/Unit/ModerationNoteMenuLocalTasksAlterTest.php
+++ b/tests/src/Unit/ModerationNoteMenuLocalTasksAlterTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\content_moderation\ModerationInformationInterface;
 use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
@@ -19,6 +20,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class ModerationNoteMenuLocalTasksAlterTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/ModerationNoteToolbarAlterTest.php b/tests/src/Unit/ModerationNoteToolbarAlterTest.php
index acc92af..ac5cc28 100644
--- a/tests/src/Unit/ModerationNoteToolbarAlterTest.php
+++ b/tests/src/Unit/ModerationNoteToolbarAlterTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\content_moderation\ModerationInformationInterface;
 use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -17,6 +18,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class ModerationNoteToolbarAlterTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/Plugin/Menu/LocalTask/AssignedNotesTest.php b/tests/src/Unit/Plugin/Menu/LocalTask/AssignedNotesTest.php
index 5d0da88..b546fc6 100644
--- a/tests/src/Unit/Plugin/Menu/LocalTask/AssignedNotesTest.php
+++ b/tests/src/Unit/Plugin/Menu/LocalTask/AssignedNotesTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit\Plugin\Menu\LocalTask;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\Core\Routing\ResettableStackedRouteMatchInterface;
 use Drupal\moderation_note\Plugin\Menu\LocalTask\AssignedNotes;
@@ -15,6 +16,7 @@ use Symfony\Component\HttpFoundation\Request;
  *
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class AssignedNotesTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/Service/MenuCountServiceTest.php b/tests/src/Unit/Service/MenuCountServiceTest.php
index 4ad226d..c0419f7 100644
--- a/tests/src/Unit/Service/MenuCountServiceTest.php
+++ b/tests/src/Unit/Service/MenuCountServiceTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\moderation_note\Unit\Service;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
@@ -14,6 +15,7 @@ use Prophecy\Prophet;
  * @coversDefaultClass \Drupal\moderation_note\Service\MenuCountService
  * @group moderation_note
  */
+#[Group('moderation_note')]
 class MenuCountServiceTest extends UnitTestCase {
 
   /**
