diff --git a/modules/ui/outlayer_ui.module b/modules/ui/outlayer_ui.module
index b5751ff..5bb928d 100644
--- a/modules/ui/outlayer_ui.module
+++ b/modules/ui/outlayer_ui.module
@@ -1,5 +1,12 @@
 <?php
 
+/**
+ * @file
+ */
+
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\outlayer_ui\Hook\OutlayerUiHooks;
+
 /**
  * @file
  * Provides the Outlayer UI.
@@ -8,31 +15,15 @@
 /**
  * Implements hook_entity_type_build().
  */
+#[LegacyHook]
 function outlayer_ui_entity_type_build(array &$entity_types) {
-  /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
-  $outlayer = $entity_types['outlayer'];
-  $outlayer->setListBuilderClass('Drupal\outlayer_ui\Controller\OutlayerListBuilder');
-  $outlayer->setFormClass('add', 'Drupal\outlayer_ui\Form\OutlayerForm');
-  $outlayer->setFormClass('edit', 'Drupal\outlayer_ui\Form\OutlayerForm');
-  $outlayer->setFormClass('delete', 'Drupal\outlayer_ui\Form\OutlayerDeleteForm');
-  $outlayer->setFormClass('duplicate', 'Drupal\outlayer_ui\Form\OutlayerForm');
-
-  $outlayer->set('admin_permission', 'administer outlayer');
-
-  $outlayer->setLinkTemplate('add-form', '/admin/structure/outlayer/add');
-  $outlayer->setLinkTemplate('edit-form', '/admin/structure/outlayer/{outlayer}');
-  $outlayer->setLinkTemplate('delete-form', '/admin/structure/outlayer/{outlayer}/delete');
-  $outlayer->setLinkTemplate('duplicate-form', '/admin/structure/outlayer/{outlayer}/duplicate');
-  $outlayer->setLinkTemplate('collection', '/admin/structure/outlayer');
+  \Drupal::service(OutlayerUiHooks::class)->entityTypeBuild($entity_types);
 }
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function outlayer_ui_help($route_name) {
-  if ($route_name == 'help.page.outlayer_ui') {
-    $output = file_get_contents(dirname(dirname(dirname(__FILE__))) . '/README.md');
-    return blazy()->markdown($output);
-  }
-  return '';
+  return \Drupal::service(OutlayerUiHooks::class)->help($route_name);
 }
diff --git a/modules/ui/outlayer_ui.services.yml b/modules/ui/outlayer_ui.services.yml
new file mode 100644
index 0000000..6183c1f
--- /dev/null
+++ b/modules/ui/outlayer_ui.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\outlayer_ui\Hook\OutlayerUiHooks:
+    class: Drupal\outlayer_ui\Hook\OutlayerUiHooks
+    autowire: true
diff --git a/modules/ui/src/Hook/OutlayerUiHooks.php b/modules/ui/src/Hook/OutlayerUiHooks.php
new file mode 100644
index 0000000..8fbcf4c
--- /dev/null
+++ b/modules/ui/src/Hook/OutlayerUiHooks.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Drupal\outlayer_ui\Hook;
+
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for outlayer_ui.
+ */
+class OutlayerUiHooks {
+  /**
+   * @file
+   * Provides the Outlayer UI.
+   */
+
+  /**
+   * Implements hook_entity_type_build().
+   */
+  #[Hook('entity_type_build')]
+  public static function entityTypeBuild(array &$entity_types) {
+    /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
+    $outlayer = $entity_types['outlayer'];
+    $outlayer->setListBuilderClass('Drupal\outlayer_ui\Controller\OutlayerListBuilder');
+    $outlayer->setFormClass('add', 'Drupal\outlayer_ui\Form\OutlayerForm');
+    $outlayer->setFormClass('edit', 'Drupal\outlayer_ui\Form\OutlayerForm');
+    $outlayer->setFormClass('delete', 'Drupal\outlayer_ui\Form\OutlayerDeleteForm');
+    $outlayer->setFormClass('duplicate', 'Drupal\outlayer_ui\Form\OutlayerForm');
+    $outlayer->set('admin_permission', 'administer outlayer');
+    $outlayer->setLinkTemplate('add-form', '/admin/structure/outlayer/add');
+    $outlayer->setLinkTemplate('edit-form', '/admin/structure/outlayer/{outlayer}');
+    $outlayer->setLinkTemplate('delete-form', '/admin/structure/outlayer/{outlayer}/delete');
+    $outlayer->setLinkTemplate('duplicate-form', '/admin/structure/outlayer/{outlayer}/duplicate');
+    $outlayer->setLinkTemplate('collection', '/admin/structure/outlayer');
+  }
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public static function help($route_name) {
+    if ($route_name == 'help.page.outlayer_ui') {
+      $output = file_get_contents(dirname(dirname(dirname(__FILE__))) . '/README.md');
+      return blazy()->markdown($output);
+    }
+    return '';
+  }
+
+}
diff --git a/outlayer.install b/outlayer.install
index d495d81..dc2bcbd 100644
--- a/outlayer.install
+++ b/outlayer.install
@@ -1,5 +1,12 @@
 <?php
 
+/**
+ * @file
+ */
+
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
+
 /**
  * @file
  * Installation actions for Outlayer.
@@ -35,7 +42,7 @@ function outlayer_requirements($phase) {
   $requirements['isotope_library'] = [
     'title'       => t('Isotope library'),
     'description' => $exists ? '' : t('The <a href=":url">Isotope library</a> should be installed at <strong>/libraries/isotope/dist/isotope.pkgd.min.js</strong>, or any path supported by libraries.module if installed. Check out file or folder permissions if troubled.', [':url' => 'https://github.com/metafizzy/isotope']),
-    '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/outlayer.module b/outlayer.module
index 75ff5ee..ad864ba 100644
--- a/outlayer.module
+++ b/outlayer.module
@@ -5,7 +5,8 @@
  * Provides Outlayer integration.
  */
 
-use Drupal\outlayer\OutlayerDefault;
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\outlayer\Hook\OutlayerHooks;
 
 /**
  * Provides a convenient shortcut for procedural hooks.
@@ -37,46 +38,39 @@ function outlayer($key = 'manager') {
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function outlayer_theme() {
-  return [
-    'gridstack__outlayer' => [
-      'render element' => 'element',
-      'base hook' => 'gridstack',
-    ],
-  ];
+  return \Drupal::service(OutlayerHooks::class)->theme();
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK_alter().
  */
+#[LegacyHook]
 function outlayer_theme_suggestions_gridstack_alter(array &$suggestions, array $variables, $hook) {
-  $settings = $variables['element']['#settings'];
-
-  if (!empty($settings['outlayer'])) {
-    $suggestions[] = 'gridstack__outlayer';
-  }
+  \Drupal::service(OutlayerHooks::class)->themeSuggestionsGridstackAlter($suggestions, $variables, $hook);
 }
 
 /**
  * Implements hook_library_info_alter().
  */
+#[LegacyHook]
 function outlayer_library_info_alter(&$libraries, $extension) {
-  /* @phpstan-ignore-next-line */
-  outlayer('hook')->libraryInfoAlter($libraries, $extension);
+  \Drupal::service(OutlayerHooks::class)->libraryInfoAlter($libraries, $extension);
 }
 
 /**
  * Implements hook_library_info_build().
  */
+#[LegacyHook]
 function outlayer_library_info_build() {
-  /* @phpstan-ignore-next-line */
-  return outlayer('hook')->libraryInfoBuild();
+  return \Drupal::service(OutlayerHooks::class)->libraryInfoBuild();
 }
 
 /**
  * Implements hook_config_schema_info_alter().
  */
+#[LegacyHook]
 function outlayer_config_schema_info_alter(array &$definitions) {
-  /* @phpstan-ignore-next-line */
-  outlayer('hook')->configSchemaInfoAlter($definitions, 'outlayer_base', OutlayerDefault::extendedSettings());
+  \Drupal::service(OutlayerHooks::class)->configSchemaInfoAlter($definitions);
 }
diff --git a/outlayer.services.yml b/outlayer.services.yml
index e9a32a8..05cde1c 100644
--- a/outlayer.services.yml
+++ b/outlayer.services.yml
@@ -10,3 +10,7 @@ services:
   outlayer.hook:
     class: Drupal\outlayer\OutlayerHook
     arguments: ['@file_system', '@outlayer.manager']
+
+  Drupal\outlayer\Hook\OutlayerHooks:
+    class: Drupal\outlayer\Hook\OutlayerHooks
+    autowire: true
diff --git a/src/Hook/OutlayerHooks.php b/src/Hook/OutlayerHooks.php
new file mode 100644
index 0000000..7bad5e7
--- /dev/null
+++ b/src/Hook/OutlayerHooks.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Drupal\outlayer\Hook;
+
+use Drupal\outlayer\OutlayerDefault;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for outlayer.
+ */
+class OutlayerHooks {
+  // @codingStandardsIgnoreEnd
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public static function theme() {
+    return [
+      'gridstack__outlayer' => [
+        'render element' => 'element',
+        'base hook' => 'gridstack',
+      ],
+    ];
+  }
+
+  /**
+   * Implements hook_theme_suggestions_HOOK_alter().
+   */
+  #[Hook('theme_suggestions_gridstack_alter')]
+  public static function themeSuggestionsGridstackAlter(array &$suggestions, array $variables, $hook) {
+    $settings = $variables['element']['#settings'];
+    if (!empty($settings['outlayer'])) {
+      $suggestions[] = 'gridstack__outlayer';
+    }
+  }
+
+  /**
+   * Implements hook_library_info_alter().
+   */
+  #[Hook('library_info_alter')]
+  public static function libraryInfoAlter(&$libraries, $extension) {
+    /* @phpstan-ignore-next-line */
+    outlayer('hook')->libraryInfoAlter($libraries, $extension);
+  }
+
+  /**
+   * Implements hook_library_info_build().
+   */
+  #[Hook('library_info_build')]
+  public static function libraryInfoBuild() {
+    /* @phpstan-ignore-next-line */
+    return outlayer('hook')->libraryInfoBuild();
+  }
+
+  /**
+   * Implements hook_config_schema_info_alter().
+   */
+  #[Hook('config_schema_info_alter')]
+  public static function configSchemaInfoAlter(array &$definitions) {
+    /* @phpstan-ignore-next-line */
+    outlayer('hook')->configSchemaInfoAlter($definitions, 'outlayer_base', OutlayerDefault::extendedSettings());
+  }
+
+}
diff --git a/src/OutlayerHook.php b/src/OutlayerHook.php
index 148e211..cf958ab 100644
--- a/src/OutlayerHook.php
+++ b/src/OutlayerHook.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\outlayer;
 
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\Core\File\FileSystem;
 use Drupal\Core\Template\Attribute;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -132,7 +133,7 @@ class OutlayerHook implements OutlayerHookInterface {
         $library = $this->manager->getLibrariesPath($id) ?: $this->manager->getLibrariesPath($id . '-layout');
         if ($library) {
           foreach ($libraries[$id]['js'] as $uri => $info) {
-            $basename = $this->fileSystem->basename($uri);
+            $basename = DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.3.0', fn() => basename($uri), fn() => $this->fileSystem->basename($uri));
             // @todo when we do not use .pkgd.min.js, extract from sources:
             // @todo $library = $id == 'masonry' ? $library : $library . '/js';
             // @todo $library = strpos($uri, 'layout-modes') !== FALSE ? $library . '/layout-modes' : $library;
diff --git a/src/Plugin/views/style/OutlayerViewsIsotope.php b/src/Plugin/views/style/OutlayerViewsIsotope.php
index b48eb18..a7ecf66 100644
--- a/src/Plugin/views/style/OutlayerViewsIsotope.php
+++ b/src/Plugin/views/style/OutlayerViewsIsotope.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\outlayer\Plugin\views\style;
 
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\views\Views;
 
 /**
@@ -113,7 +114,7 @@ class OutlayerViewsIsotope extends OutlayerViewsGridStack {
     }
 
     $results = [];
-    if (!empty($field_name) && $view_results = views_get_view_result($view_id, $display_id)) {
+    if (!empty($field_name) && $view_results = DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => Views::getViewResult($view_id, $display_id), fn() => views_get_view_result($view_id, $display_id))) {
       foreach ($view_results as $delta => $row) {
         $style->view->row_index = $delta;
 
@@ -158,7 +159,7 @@ class OutlayerViewsIsotope extends OutlayerViewsGridStack {
     }
 
     $results = $keys = [];
-    if (!empty($fields) && $view_results = views_get_view_result($view_id, $display_id)) {
+    if (!empty($fields) && $view_results = DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => Views::getViewResult($view_id, $display_id), fn() => views_get_view_result($view_id, $display_id))) {
       foreach ($view_results as $delta => $row) {
         $style->view->row_index = $delta;
 
