diff --git a/dropzonejs.install b/dropzonejs.install
index a955c72..4751f36 100644
--- a/dropzonejs.install
+++ b/dropzonejs.install
@@ -5,7 +5,8 @@
  * Install, update and uninstall functions for the dropzonejs module.
  */
 
-use Drupal\Core\Asset\LibraryDiscoveryInterface;
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
 
 /**
  * Implements hook_requirements().
@@ -35,7 +36,7 @@ function dropzonejs_requirements($phase) {
     $requirements['dropzonejs_library'] = [
       'title' => t('Dropzone library found'),
       'description' => t('Library location: @js_path', ['@js_path' => $js_path]),
-      'severity' => REQUIREMENT_OK,
+      'severity' => DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::OK, fn() => REQUIREMENT_OK),
     ];
   }
   else {
@@ -44,7 +45,7 @@ function dropzonejs_requirements($phase) {
       'description' => t('Dropzonejs requires the dropzone.min.js library.
         Download it (https://github.com/dropzone/dropzone) and place it in the
         libraries folder (/libraries)'),
-      'severity' => REQUIREMENT_ERROR,
+      'severity' => DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::Error, fn() => REQUIREMENT_ERROR),
     ];
   }
 
@@ -59,7 +60,7 @@ function dropzonejs_update_8001() {
   $config = $config_factory->getEditable('dropzonejs.settings');
   $config->clear('tmp_dir');
   $config->set('tmp_upload_scheme', 'temporary');
-  $config->save(TRUE);
+  $config->save();
 }
 
 /**
@@ -70,7 +71,7 @@ function dropzonejs_update_8002() {
   $config = $config_factory->getEditable('dropzonejs.settings');
   $config->clear('filename_transliteration');
   $config->set('filename_transliteration', TRUE);
-  $config->save(TRUE);
+  $config->save();
 }
 
 /**
@@ -81,5 +82,5 @@ function dropzonejs_update_8003() {
   $config = $config_factory->getEditable('dropzonejs.settings');
   $config->clear('upload_timeout_ms');
   $config->set('upload_timeout_ms', 0);
-  $config->save(TRUE);
+  $config->save();
 }
diff --git a/dropzonejs.module b/dropzonejs.module
index 573034b..923e34a 100644
--- a/dropzonejs.module
+++ b/dropzonejs.module
@@ -5,34 +5,25 @@
  * Contains dropzonejs.module.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\dropzonejs\Hook\DropzonejsHooks;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\dropzonejs\Form\DropzoneJsUploadForm;
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function dropzonejs_help($route_name, RouteMatchInterface $route_match) {
-  $output = '';
-  switch ($route_name) {
-    // Main module help for the dropzonejs module.
-    case 'help.page.dropzonejs':
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('DropzoneJS') . '</p>';
-    default:
-  }
-  return $output;
+  return \Drupal::service(DropzonejsHooks::class)->help($route_name, $route_match);
 }
 
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function dropzonejs_theme() {
-  return [
-    'dropzonejs' => [
-      'render element' => 'element',
-    ],
-  ];
+  return \Drupal::service(DropzonejsHooks::class)->theme();
 }
 
 /**
@@ -69,105 +60,33 @@ function template_preprocess_dropzonejs(array &$variables) {
 /**
  * Implements hook_library_info_build().
  */
+#[LegacyHook]
 function dropzonejs_library_info_build() {
-  $libraries = [];
-
-  /** @var \Drupal\Core\Asset\LibrariesDirectoryFileFinder $library_file_finder */
-  $library_file_finder = \Drupal::service('library.libraries_directory_file_finder');
-  $exif_path = $library_file_finder->find('exif-js/exif.js');
-
-  if ($exif_path && file_exists($exif_path)) {
-    $libraries['exif-js'] = [
-      'title' => 'Exif',
-      'website' => 'https://github.com/exif-js/exif-js',
-      'version' => 'v2.3.0',
-      'license' => [
-        'name' => 'MIT',
-        'url' => 'https://github.com/exif-js/exif-js/blob/master/LICENSE.md',
-        'gpl-compatible' => TRUE,
-      ],
-      'js' => [
-        '/libraries/exif-js/exif.js' => [],
-      ],
-    ];
-
-  }
-
-  return $libraries;
+  return \Drupal::service(DropzonejsHooks::class)->libraryInfoBuild();
 }
 
 /**
  * Implements hook_library_info_alter().
  */
+#[LegacyHook]
 function dropzonejs_library_info_alter(&$libraries, $extension) {
-  if ($extension !== 'dropzonejs') {
-    return;
-  }
-
-  /** @var \Drupal\Core\Asset\LibrariesDirectoryFileFinder $library_file_finder */
-  $library_file_finder = \Drupal::service('library.libraries_directory_file_finder');
-
-  $js_candidates = [
-    'dropzone/dropzone-min.js',
-    'dropzone/dropzone.min.js',
-    'dropzone/min/dropzone.min.js',
-    'dropzone/dist/dropzone-min.js',
-    'dropzone/dist/min/dropzone.min.js',
-  ];
-  foreach ($js_candidates as $js_candidate) {
-    if ($js_min_path = $library_file_finder->find($js_candidate)) {
-      $libraries['dropzonejs']['js'] = ['/' . $js_min_path => []];
-    }
-  }
-
-  $css_candidates = [
-    'dropzone/dropzone.css',
-    'dropzone/min/dropzone.min.css',
-    'dropzone/dist/dropzone.css',
-    'dropzone/dist/min/dropzone.min.css',
-  ];
-  foreach ($css_candidates as $css_candidate) {
-    if ($css_path = $library_file_finder->find($css_candidate)) {
-      $libraries['dropzonejs']['css']['component'] = ['/' . $css_path => []];
-    }
-  }
+  \Drupal::service(DropzonejsHooks::class)->libraryInfoAlter($libraries, $extension);
 }
 
 /**
  * Implements hook_media_source_info_alter().
  */
+#[LegacyHook]
 function dropzonejs_media_source_info_alter(array &$sources) {
-  if (isset($sources['image'])) {
-    $sources['image']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
-  }
-
-  if (isset($sources['video_file'])) {
-    $sources['video_file']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
-  }
-
-  if (isset($sources['audio_file'])) {
-    $sources['audio_file']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
-  }
-
-  if (isset($sources['file'])) {
-    $sources['file']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
-  }
+  \Drupal::service(DropzonejsHooks::class)->mediaSourceInfoAlter($sources);
 }
 
 /**
  * Implements hook_form_FORM_ID_alter().
  */
+#[LegacyHook]
 function dropzonejs_form_system_file_system_settings_alter(array &$form, FormStateInterface $form_state) {
-  $dropzone_config = \Drupal::config('dropzonejs.settings');
-
-  $form['dropzonejs_filename_sanitization'] = [
-    '#type' => 'checkbox',
-    '#title' => t('Enable custom filename sanitization and transliteration for DropzoneJS (deprecated)'),
-    '#description' => t('When enabled, files uploaded through DropzoneJS go through a hardcoded and not customizable sanitization/transliteration process. Starting with Drupal 10.2, site-wide transliteration options are available that also always apply to files uploaded through DropzoneJS. It is recommend to configure those settings and disable this. This feature will be removed in a future version.'),
-    '#weight' => 99,
-    '#default_value' => $dropzone_config->get('filename_transliteration'),
-  ];
-  $form['#submit'][] = 'dropzonejs_form_system_file_system_settings_submit';
+  \Drupal::service(DropzonejsHooks::class)->formSystemFileSystemSettingsAlter($form, $form_state);
 }
 
 /**
diff --git a/dropzonejs.services.yml b/dropzonejs.services.yml
index f5c2bf7..ce4b762 100644
--- a/dropzonejs.services.yml
+++ b/dropzonejs.services.yml
@@ -5,3 +5,7 @@ services:
   dropzonejs.upload_handler:
     class: Drupal\dropzonejs\UploadHandler
     arguments: ['@request_stack', '@config.factory', '@transliteration', '@language_manager', '@event_dispatcher']
+
+  Drupal\dropzonejs\Hook\DropzonejsHooks:
+    class: Drupal\dropzonejs\Hook\DropzonejsHooks
+    autowire: true
diff --git a/src/Controller/UploadController.php b/src/Controller/UploadController.php
index 6e9b588..c617c7d 100644
--- a/src/Controller/UploadController.php
+++ b/src/Controller/UploadController.php
@@ -63,14 +63,14 @@ class UploadController extends ControllerBase {
       throw new AccessDeniedHttpException();
     }
 
-    // @todo: Implement file_validate_size();
+    // @todo Implement file_validate_size();
     try {
-      /* @var \Drupal\Core\File\FileSystem $file_system */
+      /** @var \Drupal\Core\File\FileSystem $file_system */
       $file_system = \Drupal::service('file_system');
       // Return JSON-RPC response.
       return new AjaxResponse([
         'jsonrpc' => '2.0',
-        'result' => $file_system->basename($this->uploadHandler->handleUpload($file)),
+        'result' => basename($this->uploadHandler->handleUpload($file)),
         'id' => 'id',
       ]);
     }
diff --git a/src/DropzoneJsUploadSave.php b/src/DropzoneJsUploadSave.php
index 9bd61c8..f40f625 100644
--- a/src/DropzoneJsUploadSave.php
+++ b/src/DropzoneJsUploadSave.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\dropzonejs;
 
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\File\FileExists;
 use Drupal\Component\Render\PlainTextOutput;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -13,7 +16,6 @@ use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Utility\Token;
 use Drupal\file\FileInterface;
-use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
 use Drupal\Core\File\FileSystemInterface;
 
 /**
@@ -111,7 +113,7 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
    * @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
    *   The stream wrapper manager.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, \Symfony\Component\Mime\MimeTypeGuesserInterface $mimetype_guesser, FileSystemInterface $file_system, LoggerChannelFactoryInterface $logger_factory, RendererInterface $renderer, ConfigFactoryInterface $config_factory, Token $token, MessengerInterface $messenger, StreamWrapperManagerInterface $stream_wrapper_manager) {
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, MimeTypeGuesserInterface $mimetype_guesser, FileSystemInterface $file_system, LoggerChannelFactoryInterface $logger_factory, RendererInterface $renderer, ConfigFactoryInterface $config_factory, Token $token, MessengerInterface $messenger, StreamWrapperManagerInterface $stream_wrapper_manager) {
     $this->entityTypeManager = $entity_type_manager;
     $this->mimeTypeGuesser = $mimetype_guesser;
     $this->fileSystem = $file_system;
@@ -166,7 +168,7 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
           '#items' => $errors,
         ],
       ];
-      $this->messenger->addError($this->renderer->renderPlain($message));
+      $this->messenger->addError(DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.3.0', fn() => $this->renderer->renderInIsolation($message), fn() => $this->renderer->renderPlain($message)));
       return FALSE;
     }
 
@@ -284,7 +286,7 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
     if (substr($destination, -1) != '/') {
       $destination .= '/';
     }
-    $destination = $this->fileSystem->getDestinationFilename($destination . $file->getFilename(), FileSystemInterface::EXISTS_RENAME);
+    $destination = $this->fileSystem->getDestinationFilename($destination . $file->getFilename(), DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.3.0', fn() => FileExists::Rename, fn() => FileSystemInterface::EXISTS_RENAME));
     $file->setFileUri($destination);
     return TRUE;
   }
diff --git a/src/Hook/DropzonejsHooks.php b/src/Hook/DropzonejsHooks.php
new file mode 100644
index 0000000..1bb7adb
--- /dev/null
+++ b/src/Hook/DropzonejsHooks.php
@@ -0,0 +1,146 @@
+<?php
+
+namespace Drupal\dropzonejs\Hook;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\dropzonejs\Form\DropzoneJsUploadForm;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Hook implementations for dropzonejs.
+ */
+class DropzonejsHooks {
+  use StringTranslationTrait;
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public function help($route_name, RouteMatchInterface $route_match) {
+    $output = '';
+    switch ($route_name) {
+      // Main module help for the dropzonejs module.
+      case 'help.page.dropzonejs':
+        $output .= '<h3>' . $this->t('About') . '</h3>';
+        $output .= '<p>' . $this->t('DropzoneJS') . '</p>';
+      default:
+    }
+    return $output;
+  }
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public static function theme() {
+    return [
+      'dropzonejs' => [
+        'render element' => 'element',
+      ],
+    ];
+  }
+
+  /**
+   * Implements hook_library_info_build().
+   */
+  #[Hook('library_info_build')]
+  public static function libraryInfoBuild() {
+    $libraries = [];
+    /** @var \Drupal\Core\Asset\LibrariesDirectoryFileFinder $library_file_finder */
+    $library_file_finder = \Drupal::service('library.libraries_directory_file_finder');
+    $exif_path = $library_file_finder->find('exif-js/exif.js');
+    if ($exif_path && file_exists($exif_path)) {
+      $libraries['exif-js'] = [
+        'title' => 'Exif',
+        'website' => 'https://github.com/exif-js/exif-js',
+        'version' => 'v2.3.0',
+        'license' => [
+          'name' => 'MIT',
+          'url' => 'https://github.com/exif-js/exif-js/blob/master/LICENSE.md',
+          'gpl-compatible' => TRUE,
+        ],
+        'js' => [
+          '/libraries/exif-js/exif.js' => [],
+        ],
+      ];
+    }
+    return $libraries;
+  }
+
+  /**
+   * Implements hook_library_info_alter().
+   */
+  #[Hook('library_info_alter')]
+  public static function libraryInfoAlter(&$libraries, $extension) {
+    if ($extension !== 'dropzonejs') {
+      return;
+    }
+    /** @var \Drupal\Core\Asset\LibrariesDirectoryFileFinder $library_file_finder */
+    $library_file_finder = \Drupal::service('library.libraries_directory_file_finder');
+    $js_candidates = [
+      'dropzone/dropzone-min.js',
+      'dropzone/dropzone.min.js',
+      'dropzone/min/dropzone.min.js',
+      'dropzone/dist/dropzone-min.js',
+      'dropzone/dist/min/dropzone.min.js',
+    ];
+    foreach ($js_candidates as $js_candidate) {
+      if ($js_min_path = $library_file_finder->find($js_candidate)) {
+        $libraries['dropzonejs']['js'] = [
+          '/' . $js_min_path => [],
+        ];
+      }
+    }
+    $css_candidates = [
+      'dropzone/dropzone.css',
+      'dropzone/min/dropzone.min.css',
+      'dropzone/dist/dropzone.css',
+      'dropzone/dist/min/dropzone.min.css',
+    ];
+    foreach ($css_candidates as $css_candidate) {
+      if ($css_path = $library_file_finder->find($css_candidate)) {
+        $libraries['dropzonejs']['css']['component'] = [
+          '/' . $css_path => [],
+        ];
+      }
+    }
+  }
+
+  /**
+   * Implements hook_media_source_info_alter().
+   */
+  #[Hook('media_source_info_alter')]
+  public static function mediaSourceInfoAlter(array &$sources) {
+    if (isset($sources['image'])) {
+      $sources['image']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
+    }
+    if (isset($sources['video_file'])) {
+      $sources['video_file']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
+    }
+    if (isset($sources['audio_file'])) {
+      $sources['audio_file']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
+    }
+    if (isset($sources['file'])) {
+      $sources['file']['forms']['media_library_add'] = DropzoneJsUploadForm::class;
+    }
+  }
+
+  /**
+   * Implements hook_form_FORM_ID_alter().
+   */
+  #[Hook('form_system_file_system_settings_alter')]
+  public function formSystemFileSystemSettingsAlter(array &$form, FormStateInterface $form_state) {
+    $dropzone_config = \Drupal::config('dropzonejs.settings');
+    $form['dropzonejs_filename_sanitization'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Enable custom filename sanitization and transliteration for DropzoneJS (deprecated)'),
+      '#description' => $this->t('When enabled, files uploaded through DropzoneJS go through a hardcoded and not customizable sanitization/transliteration process. Starting with Drupal 10.2, site-wide transliteration options are available that also always apply to files uploaded through DropzoneJS. It is recommend to configure those settings and disable this. This feature will be removed in a future version.'),
+      '#weight' => 99,
+      '#default_value' => $dropzone_config->get('filename_transliteration'),
+    ];
+    $form['#submit'][] = 'dropzonejs_form_system_file_system_settings_submit';
+  }
+
+}
diff --git a/tests/src/FunctionalJavascript/DropzoneJsEbWidgetTest.php b/tests/src/FunctionalJavascript/DropzoneJsEbWidgetTest.php
index b3cc150..209bd17 100644
--- a/tests/src/FunctionalJavascript/DropzoneJsEbWidgetTest.php
+++ b/tests/src/FunctionalJavascript/DropzoneJsEbWidgetTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\dropzonejs\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
  *
  * @group dropzonejs
  */
+#[Group('dropzonejs')]
+#[RunTestsInSeparateProcesses]
 class DropzoneJsEbWidgetTest extends DropzoneJsWebDriverTestBase {
 
   use FieldUiTestTrait;
diff --git a/tests/src/Kernel/DropzoneJsElementTest.php b/tests/src/Kernel/DropzoneJsElementTest.php
index 0714f1b..f7f3540 100644
--- a/tests/src/Kernel/DropzoneJsElementTest.php
+++ b/tests/src/Kernel/DropzoneJsElementTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\dropzonejs\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\user\Entity\Role;
 use Drupal\user\RoleInterface;
@@ -11,6 +13,8 @@ use Drupal\user\RoleInterface;
  *
  * @group dropzonejs
  */
+#[Group('dropzonejs')]
+#[RunTestsInSeparateProcesses]
 class DropzoneJsElementTest extends KernelTestBase {
 
   /**
diff --git a/tests/src/Kernel/DropzoneJsUploadControllerTest.php b/tests/src/Kernel/DropzoneJsUploadControllerTest.php
index c97d783..ef2d2a5 100644
--- a/tests/src/Kernel/DropzoneJsUploadControllerTest.php
+++ b/tests/src/Kernel/DropzoneJsUploadControllerTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\dropzonejs\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\dropzonejs\Controller\UploadController;
 use Drupal\KernelTests\KernelTestBase;
 use Symfony\Component\HttpFoundation\File\UploadedFile;
@@ -15,6 +17,8 @@ use Drupal\language\Entity\ConfigurableLanguage;
  *
  * @group dropzonejs
  */
+#[Group('dropzonejs')]
+#[RunTestsInSeparateProcesses]
 class DropzoneJsUploadControllerTest extends KernelTestBase {
 
   /**
diff --git a/tests/src/Kernel/DropzoneRequirementsTest.php b/tests/src/Kernel/DropzoneRequirementsTest.php
index 1cf503a..a10cc66 100644
--- a/tests/src/Kernel/DropzoneRequirementsTest.php
+++ b/tests/src/Kernel/DropzoneRequirementsTest.php
@@ -2,15 +2,19 @@
 
 namespace Drupal\Tests\dropzonejs\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
 use Drupal\KernelTests\KernelTestBase;
-use Drupal\user\Entity\Role;
-use Drupal\user\RoleInterface;
 
 /**
  * Tests related to the DropzoneJS requirements checks.
  *
  * @group dropzonejs
  */
+#[Group('dropzonejs')]
+#[RunTestsInSeparateProcesses]
 class DropzoneRequirementsTest extends KernelTestBase {
 
   /**
@@ -31,7 +35,7 @@ class DropzoneRequirementsTest extends KernelTestBase {
   public function testRequirements() {
     \Drupal::moduleHandler()->loadInclude('dropzonejs', 'install');
     $requirements = dropzonejs_requirements('runtime');
-    $this->assertEquals(REQUIREMENT_OK, $requirements['dropzonejs_library']['severity']);
+    $this->assertEquals(DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => RequirementSeverity::OK, fn() => REQUIREMENT_OK), $requirements['dropzonejs_library']['severity']);
     $this->assertEquals('Dropzone library found', (string) $requirements['dropzonejs_library']['title']);
     $this->assertStringContainsString('Library location: libraries/dropzone/', (string) $requirements['dropzonejs_library']['description']);
   }
