diff --git a/src/Hook/VotingapiWidgetsHooks.php b/src/Hook/VotingapiWidgetsHooks.php
new file mode 100644
index 0000000..7310b16
--- /dev/null
+++ b/src/Hook/VotingapiWidgetsHooks.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Drupal\votingapi_widgets\Hook;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for votingapi_widgets.
+ */
+class VotingapiWidgetsHooks {
+
+  /**
+   * Implements hook_theme_suggestions_alter().
+   */
+  #[Hook('theme_suggestions_alter')]
+  public function themeSuggestionsAlter(array &$suggestions, array $variables, $hook) {
+    if ($hook == 'votingapi_widgets_summary') {
+      $entity = $variables['vote'];
+      $content = \Drupal::service('entity_type.manager')->getStorage($entity->getVotedEntityType())->load($entity->getVotedEntityId());
+      $fieldSettings = FieldConfig::loadByName($content->getEntityTypeId(), $content->bundle(), $variables['field_name']);
+      $plugin = $fieldSettings->getSetting('vote_plugin');
+      $suggestions[] = $hook . '__' . $plugin;
+      $suggestions[] = $hook . '__' . $plugin . '__' . $entity->field_name->value;
+      $suggestions[] = $hook . '__' . $plugin . '__' . $content->getEntityTypeId();
+      $suggestions[] = $hook . '__' . $plugin . '__' . $content->getEntityTypeId() . '__' . $content->bundle() . '__' . $entity->field_name->value;
+      $suggestions[] = $hook . '__' . $plugin . '__' . $content->getEntityTypeId() . '__' . $content->bundle();
+    }
+  }
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public function theme() {
+    return [
+      'votingapi_widgets_summary' => [
+        'variables' => [
+          'results' => [],
+          'vote' => NULL,
+          'field_name' => NULL,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * Implements hook_preprocess_HOOK() for the voting_widgets_summary template.
+   */
+  #[Hook('preprocess_votingapi_widgets_summary')]
+  public function preprocessVotingapiWidgetsSummary(array &$variables) {
+    // If all votes have been deleted the vote_field_count variable is zero
+    // instead of a default empty array.
+    // Here we set vote_field_count to 0 if the results array is empty so it can
+    // be more easily checked in the Twig template.
+    if (empty($variables['results'])) {
+      $variables['results']['vote_field_count'] = 0;
+    }
+  }
+
+}
diff --git a/tests/src/Functional/UninstallTest.php b/tests/src/Functional/UninstallTest.php
index b285317..2c16f18 100644
--- a/tests/src/Functional/UninstallTest.php
+++ b/tests/src/Functional/UninstallTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\votingapi_widgets\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\Extension\ModuleUninstallValidatorException;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\field\Entity\FieldConfig;
@@ -14,6 +16,8 @@ use Drupal\user\RoleInterface;
  *
  * @group votingapi_widgets
  */
+#[Group('votingapi_widgets')]
+#[RunTestsInSeparateProcesses]
 class UninstallTest extends BrowserTestBase {
 
   /**
diff --git a/tests/src/Functional/VotingApiFieldTest.php b/tests/src/Functional/VotingApiFieldTest.php
index 4f1a3d0..5bafe60 100644
--- a/tests/src/Functional/VotingApiFieldTest.php
+++ b/tests/src/Functional/VotingApiFieldTest.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\votingapi_widgets\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -11,6 +13,8 @@ use Drupal\Tests\BrowserTestBase;
  *
  * @group votingapi_widgets
  */
+#[Group('votingapi_widgets')]
+#[RunTestsInSeparateProcesses]
 class VotingApiFieldTest extends BrowserTestBase {
 
   /**
diff --git a/tests/src/Unit/VotingApiLazyLoaderTest.php b/tests/src/Unit/VotingApiLazyLoaderTest.php
index 0b198fc..2244952 100644
--- a/tests/src/Unit/VotingApiLazyLoaderTest.php
+++ b/tests/src/Unit/VotingApiLazyLoaderTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\votingapi_widgets\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Tests\UnitTestCase;
 use Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager;
@@ -14,6 +15,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\votingapi_widgets\VotingApiLazyLoader
  * @group votingapi_widgets
  */
+#[Group('votingapi_widgets')]
 class VotingApiLazyLoaderTest extends UnitTestCase {
   use ProphecyTrait;
 
diff --git a/votingapi_widgets.install b/votingapi_widgets.install
index af35922..d353d72 100644
--- a/votingapi_widgets.install
+++ b/votingapi_widgets.install
@@ -1,5 +1,12 @@
 <?php
 
+/**
+ * @file
+ */
+
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
+
 /**
  * @file
  * Install, update and uninstall functions for the votingapi_widgets module.
@@ -18,7 +25,7 @@ function votingapi_widgets_requirements($phase) {
     $requirements['jquery_bar_rating'] = [
       'title'       => t('jquery-bar-rating'),
       'description' => $exists ? '' : t('The <a href=":url">jQuery Bar Rating Plugin</a> should be installed at <strong>/libraries/jquery-bar-rating/dist/jquery.barrating.min.js</strong>. Check out file or folder permissions if troubled.', [':url' => 'https://github.com/antennaio/jquery-bar-rating']),
-      'severity'    => $exists ? REQUIREMENT_OK : REQUIREMENT_ERROR,
+      'severity'    => $exists ? DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::OK, fn() => REQUIREMENT_OK) : DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::Error, fn() => REQUIREMENT_ERROR),
       'value'       => $exists ? t('Installed') : t('Not installed'),
     ];
   }
diff --git a/votingapi_widgets.module b/votingapi_widgets.module
index 83be818..99e73e7 100644
--- a/votingapi_widgets.module
+++ b/votingapi_widgets.module
@@ -5,11 +5,11 @@
  * Contains votingapi_widgets.module.
  */
 
+use Drupal\votingapi_widgets\Hook\VotingapiWidgetsHooks;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Hook\Attribute\LegacyHook;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\field\Entity\FieldConfig;
 use Drupal\votingapi_widgets\Hook\VotingApiWidgetsEntityHooks;
 use Drupal\votingapi_widgets\Hook\VotingApiWidgetsFormHooks;
 use Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks;
@@ -49,45 +49,23 @@ function votingapi_widgets_form_field_config_edit_form_alter(&$form, FormStateIn
 /**
  * Implements hook_theme_suggestions_alter().
  */
+#[LegacyHook]
 function votingapi_widgets_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
-  if ($hook == 'votingapi_widgets_summary') {
-    $entity = $variables['vote'];
-    $content = \Drupal::service('entity_type.manager')->getStorage($entity->getVotedEntityType())->load($entity->getVotedEntityId());
-    $fieldSettings = FieldConfig::loadByName($content->getEntityTypeId(), $content->bundle(), $variables['field_name']);
-    $plugin = $fieldSettings->getSetting('vote_plugin');
-
-    $suggestions[] = $hook . '__' . $plugin;
-    $suggestions[] = $hook . '__' . $plugin . '__' . $entity->field_name->value;
-    $suggestions[] = $hook . '__' . $plugin . '__' . $content->getEntityTypeId();
-    $suggestions[] = $hook . '__' . $plugin . '__' . $content->getEntityTypeId() . '__' . $content->bundle() . '__' . $entity->field_name->value;
-    $suggestions[] = $hook . '__' . $plugin . '__' . $content->getEntityTypeId() . '__' . $content->bundle();
-  }
+  \Drupal::service(VotingapiWidgetsHooks::class)->themeSuggestionsAlter($suggestions, $variables, $hook);
 }
 
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function votingapi_widgets_theme() {
-  return [
-    'votingapi_widgets_summary' => [
-      'variables' => [
-        'results' => [],
-        'vote'    => NULL,
-        'field_name'  => NULL,
-      ],
-    ],
-  ];
+  return \Drupal::service(VotingapiWidgetsHooks::class)->theme();
 }
 
 /**
  * Implements hook_preprocess_HOOK() for the voting_widgets_summary template.
  */
+#[LegacyHook]
 function votingapi_widgets_preprocess_votingapi_widgets_summary(array &$variables) {
-  // If all votes have been deleted the vote_field_count variable is zero
-  // instead of a default empty array.
-  // Here we set vote_field_count to 0 if the results array is empty so it can
-  // be more easily checked in the Twig template.
-  if (empty($variables['results'])) {
-    $variables['results']['vote_field_count'] = 0;
-  }
+  \Drupal::service(VotingapiWidgetsHooks::class)->preprocessVotingapiWidgetsSummary($variables);
 }
diff --git a/votingapi_widgets.services.yml b/votingapi_widgets.services.yml
index 4c0cc1a..a4edeb4 100644
--- a/votingapi_widgets.services.yml
+++ b/votingapi_widgets.services.yml
@@ -18,3 +18,7 @@ services:
   Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks:
     class: \Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks
     autowire: true
+
+  Drupal\votingapi_widgets\Hook\VotingapiWidgetsHooks:
+    class: Drupal\votingapi_widgets\Hook\VotingapiWidgetsHooks
+    autowire: true
