diff --git a/image_pointer.module b/image_pointer.module
index 4f776b9..629d34b 100644
--- a/image_pointer.module
+++ b/image_pointer.module
@@ -4,7 +4,9 @@
  * @file
  * Server and database details.
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\image_pointer\Hook\ImagePointerHooks;
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\file\Entity\File;
@@ -13,94 +15,25 @@ use Drupal\Core\Form\FormStateInterface;
 /**
  * Implements hook_form_alter().
  */
-function image_pointer_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
-  $config = \Drupal::config('image_pointer.settings')->get();  
-  if($form_id == "node_{$config['content_type']}_form" || $form_id == "node_{$config['content_type']}_edit_form") {
-    $form['#attached']['library'][] = 'image_pointer/image_pointer.lib';
-    $file = File::load($config['image'][0]);  
-    $file_marker = File::load($config['image_pointer'][0]);
-   
-    if(!empty($file) && !empty($file_marker)) {
-      $url = $file->createFileUrl();
-      $marker_url = $file_marker->createFileUrl();
-      $block_title = $config['block_title'];     
-      $pointerX = 0;
-      $pointerY = 0;
-      if(isset($form['field_image_pointer_xy'])) {
-        $field_image_pointer_xy = $form['field_image_pointer_xy']['widget'][0]['#default_value'];
-        if (is_null($field_image_pointer_xy)) {
-          $arr_coord = [0, 0];
-        }
-        else {
-          $arr_coord = explode(',', $field_image_pointer_xy);
-        }
-        $pointerX = $arr_coord[0];
-        $pointerY = $arr_coord[1];
-      }
-     // $arr_coord = explode(',', $pointer);
-        //  $contents[$key]['pointerX'] = $arr_coord[0];
-         // $contents[$key]['pointerY'] = $arr_coord[1]; 
-      $arr_val = [
-        'image_url' => $url,
-        'marker_url' => $marker_url,
-        'image_width' => $config['image_width'],
-        'image_height' => $config['image_height'],
-        'marker_width' => $config['marker_width'],
-        'marker_height' => $config['marker_height'],
-        'block_title' => $block_title,
-        'pointerX' => $pointerX,
-        'pointerY' => $pointerY
-      ];
-      $image_pointer_twig = [
-        '#theme' => 'image_pointer',
-        '#arg' => $arr_val,
-      ];      
-      $output = \Drupal::service('renderer')->renderPlain($image_pointer_twig);
-      $form['imagemap'] = [
-        '#type' => 'markup',
-        '#markup' => $output,
-        '#weight' => $form['field_image_pointer_xy']['#weight'] -1,
-      ];
-      //print_r($output);
-      //exit;
-    }     
-  }  
+#[LegacyHook]
+function image_pointer_form_alter(array &$form, FormStateInterface $form_state, $form_id)
+{
+    \Drupal::service(ImagePointerHooks::class)->formAlter($form, $form_state, $form_id);
 }
 
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function image_pointer_theme() {
-    return [
-      'image_pointer' => [
-      'variables' => ['arg' => NULL],
-      'template' => 'image--pointer',
-      ],
-      'image_pointer_view' => [
-        'variables' => ['contents' => NULL, 'arg' => NULL],
-        'template' => 'image--pointer--view',
-      ],
-    ];
+    return \Drupal::service(ImagePointerHooks::class)->theme();
   }
 
 /**
  * Implements hook_help().
  */
-function image_pointer_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.image_pointer':
-    $text = file_get_contents(__DIR__ . '/README.txt');
-    if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
-      return '<pre>' . Html::escape($text) . '</pre>';
-    }
-    else {
-      // Use the Markdown filter to render the README.
-      $filter_manager = \Drupal::service('plugin.manager.filter');
-      $settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
-      $config = ['settings' => $settings];
-      $filter = $filter_manager->createInstance('markdown', $config);
-      return $filter->process($text, 'en');
-    }
-  }
-return NULL;
-}
\ No newline at end of file
+#[LegacyHook]
+function image_pointer_help($route_name, RouteMatchInterface $route_match)
+{
+    return \Drupal::service(ImagePointerHooks::class)->help($route_name, $route_match);
+}
diff --git a/image_pointer.services.yml b/image_pointer.services.yml
new file mode 100644
index 0000000..ad77125
--- /dev/null
+++ b/image_pointer.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\image_pointer\Hook\ImagePointerHooks:
+    class: Drupal\image_pointer\Hook\ImagePointerHooks
+    autowire: true
diff --git a/src/Hook/ImagePointerHooks.php b/src/Hook/ImagePointerHooks.php
new file mode 100644
index 0000000..8ff4741
--- /dev/null
+++ b/src/Hook/ImagePointerHooks.php
@@ -0,0 +1,121 @@
+<?php
+
+namespace Drupal\image_pointer\Hook;
+
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Component\Utility\Html;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\file\Entity\File;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+/**
+ * Hook implementations for image_pointer.
+ */
+class ImagePointerHooks
+{
+    /**
+     * Implements hook_form_alter().
+     */
+    #[Hook('form_alter')]
+    public static function formAlter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
+    {
+        $config = \Drupal::config('image_pointer.settings')->get();
+        if ($form_id == "node_{$config['content_type']}_form" || $form_id == "node_{$config['content_type']}_edit_form") {
+            $form['#attached']['library'][] = 'image_pointer/image_pointer.lib';
+            $file = \Drupal\file\Entity\File::load($config['image'][0]);
+            $file_marker = \Drupal\file\Entity\File::load($config['image_pointer'][0]);
+            if (!empty($file) && !empty($file_marker)) {
+                $url = $file->createFileUrl();
+                $marker_url = $file_marker->createFileUrl();
+                $block_title = $config['block_title'];
+                $pointerX = 0;
+                $pointerY = 0;
+                if (isset($form['field_image_pointer_xy'])) {
+                    $field_image_pointer_xy = $form['field_image_pointer_xy']['widget'][0]['#default_value'];
+                    if (is_null($field_image_pointer_xy)) {
+                        $arr_coord = [
+                            0,
+                            0,
+                        ];
+                    } else {
+                        $arr_coord = explode(',', $field_image_pointer_xy);
+                    }
+                    $pointerX = $arr_coord[0];
+                    $pointerY = $arr_coord[1];
+                }
+                // $arr_coord = explode(',', $pointer);
+                //  $contents[$key]['pointerX'] = $arr_coord[0];
+                // $contents[$key]['pointerY'] = $arr_coord[1]; 
+                $arr_val = [
+                    'image_url' => $url,
+                    'marker_url' => $marker_url,
+                    'image_width' => $config['image_width'],
+                    'image_height' => $config['image_height'],
+                    'marker_width' => $config['marker_width'],
+                    'marker_height' => $config['marker_height'],
+                    'block_title' => $block_title,
+                    'pointerX' => $pointerX,
+                    'pointerY' => $pointerY,
+                ];
+                $image_pointer_twig = [
+                    '#theme' => 'image_pointer',
+                    '#arg' => $arr_val,
+                ];
+                $output = \Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.3.0', fn() => \Drupal::service('renderer')->renderInIsolation($image_pointer_twig), fn() => \Drupal::service('renderer')->renderPlain($image_pointer_twig));
+                $form['imagemap'] = [
+                    '#type' => 'markup',
+                    '#markup' => $output,
+                    '#weight' => $form['field_image_pointer_xy']['#weight'] - 1,
+                ];
+                //print_r($output);
+                //exit;
+            }
+        }
+    }
+    /**
+     * Implements hook_theme().
+     */
+    #[Hook('theme')]
+    public static function theme()
+    {
+        return [
+            'image_pointer' => [
+                'variables' => [
+                    'arg' => NULL,
+                ],
+                'template' => 'image--pointer',
+            ],
+            'image_pointer_view' => [
+                'variables' => [
+                    'contents' => NULL,
+                    'arg' => NULL,
+                ],
+                'template' => 'image--pointer--view',
+            ],
+        ];
+    }
+    /**
+     * Implements hook_help().
+     */
+    #[Hook('help')]
+    public static function help($route_name, \Drupal\Core\Routing\RouteMatchInterface $route_match)
+    {
+        switch ($route_name) {
+            case 'help.page.image_pointer':
+                $text = file_get_contents(__DIR__ . '/README.txt');
+                if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
+                    return '<pre>' . \Drupal\Component\Utility\Html::escape($text) . '</pre>';
+                } else {
+                    // Use the Markdown filter to render the README.
+                    $filter_manager = \Drupal::service('plugin.manager.filter');
+                    $settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
+                    $config = [
+                        'settings' => $settings,
+                    ];
+                    $filter = $filter_manager->createInstance('markdown', $config);
+                    return $filter->process($text, 'en');
+                }
+        }
+        return NULL;
+    }
+}
