diff --git a/src/Attribute/VotingApiWidget.php b/src/Attribute/VotingApiWidget.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d34acf021f1dc102481dde75be5a7dbd67ce1f2
--- /dev/null
+++ b/src/Attribute/VotingApiWidget.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\votingapi_widgets\Attribute;
+
+use Drupal\Component\Plugin\Attribute\Plugin;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+
+/**
+ * Defines a Voting API widget attribute object.
+ *
+ * Plugin Namespace: Plugin\votingapi_widgets.
+ *
+ * For a working example, see
+ * \Drupal\votingapi_widgets\Plugin\votingapi_widgets\UsefulWidget
+ *
+ * @see hook_vote_result_info_alter()
+ * @see \Drupal\votingapi_widgets\Plugin\VotingApiWidgetInterface
+ * @see \Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase
+ * @see \Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager
+ * @see plugin_api
+ */
+#[\Attribute(\Attribute::TARGET_CLASS)]
+class VotingApiWidget extends Plugin {
+
+  /**
+   * Constructs a VotingApiWidget attribute object.
+   *
+   * @param string $id
+   *   The plugin ID. The machine-name of the function plugin.
+   * @param \Drupal\Core\StringTranslation\TranslatableMarkup $label
+   *   The human-readable name of the widget.
+   * @param array $values
+   *   An array of possible vote values.
+   * @param class-string|null $deriver
+   *   (optional) The deriver class.
+   */
+  public function __construct(
+    public readonly string $id,
+    public readonly TranslatableMarkup $label,
+    public readonly array $values,
+    public readonly ?string $deriver = NULL,
+  ) {}
+
+}
diff --git a/src/Plugin/VotingApiWidgetManager.php b/src/Plugin/VotingApiWidgetManager.php
index 2e071c671e8db4998b82f53ec1c21400d36fb7eb..84b646d28c3b2cacaec5a597e8c0c2ff86fdb5f7 100644
--- a/src/Plugin/VotingApiWidgetManager.php
+++ b/src/Plugin/VotingApiWidgetManager.php
@@ -5,6 +5,7 @@ namespace Drupal\votingapi_widgets\Plugin;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\votingapi_widgets\Attribute\VotingApiWidget;
 
 /**
  * Provides the Voting api widget plugin manager.
@@ -23,7 +24,7 @@ class VotingApiWidgetManager extends DefaultPluginManager {
    *   The module handler to invoke the alter hook with.
    */
   public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/votingapi_widget', $namespaces, $module_handler, 'Drupal\votingapi_widgets\Plugin\VotingApiWidgetInterface', 'Drupal\votingapi_widgets\Annotation\VotingApiWidget');
+    parent::__construct('Plugin/VotingApiWidget', $namespaces, $module_handler, VotingApiWidgetInterface::class, VotingApiWidget::class, 'Drupal\votingapi_widgets\Annotation\VotingApiWidget');
     $this->alterInfo('votingapi_widgets_voting_api_widget_info');
     $this->setCacheBackend($cache_backend, 'votingapi_widgets_voting_api_widget_plugins');
   }
diff --git a/src/Plugin/votingapi_widget/FiveStarWidget.php b/src/Plugin/votingapi_widget/FiveStarWidget.php
index 0845de4acc67a2b65fe7529cd8429ef57d1175ab..3c2e33e26d1beeb36144d5cd3ca526daa145d5d9 100644
--- a/src/Plugin/votingapi_widget/FiveStarWidget.php
+++ b/src/Plugin/votingapi_widget/FiveStarWidget.php
@@ -3,6 +3,8 @@
 namespace Drupal\votingapi_widgets\Plugin\votingapi_widget;
 
 use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\votingapi_widgets\Attribute\VotingApiWidget;
 use Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase;
 
 /**
@@ -20,8 +22,18 @@ use Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase;
  *   },
  * )
  */
+#[VotingApiWidget(
+  id: "fivestar",
+  label: new TranslatableMarkup("Fivestar rating"),
+  values: [
+    1 => new TranslatableMarkup("Poor"),
+    2 => new TranslatableMarkup("Not so poor"),
+    3 => new TranslatableMarkup("Average"),
+    4 => new TranslatableMarkup("Good"),
+    5 => new TranslatableMarkup("Very good"),
+  ]
+)]
 class FiveStarWidget extends VotingApiWidgetBase {
-
   use StringTranslationTrait;
 
   /**
diff --git a/src/Plugin/votingapi_widget/LikeWidget.php b/src/Plugin/votingapi_widget/LikeWidget.php
index 37fdb94bdc3c3e2a44d7e0a3605bcd8c311ef98c..582af9036b39e3286c748a8755f2443b9be336e5 100644
--- a/src/Plugin/votingapi_widget/LikeWidget.php
+++ b/src/Plugin/votingapi_widget/LikeWidget.php
@@ -3,6 +3,8 @@
 namespace Drupal\votingapi_widgets\Plugin\votingapi_widget;
 
 use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\votingapi_widgets\Attribute\VotingApiWidget;
 use Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase;
 
 /**
@@ -16,8 +18,14 @@ use Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase;
  *   },
  * )
  */
+#[VotingApiWidget(
+  id: "like",
+  label: new TranslatableMarkup("Like"),
+  values: [
+    1 => new TranslatableMarkup("Like"),
+  ]
+)]
 class LikeWidget extends VotingApiWidgetBase {
-
   use StringTranslationTrait;
 
   /**
diff --git a/src/Plugin/votingapi_widget/UsefulWidget.php b/src/Plugin/votingapi_widget/UsefulWidget.php
index 56fd99d05513cd3e25a5279af970ead57e609472..f4da9a356135f268a98cd2b970a9f528d6a7d129 100644
--- a/src/Plugin/votingapi_widget/UsefulWidget.php
+++ b/src/Plugin/votingapi_widget/UsefulWidget.php
@@ -3,6 +3,8 @@
 namespace Drupal\votingapi_widgets\Plugin\votingapi_widget;
 
 use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\votingapi_widgets\Attribute\VotingApiWidget;
 use Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase;
 
 /**
@@ -17,8 +19,15 @@ use Drupal\votingapi_widgets\Plugin\VotingApiWidgetBase;
  *   },
  * )
  */
+#[VotingApiWidget(
+  id: "useful",
+  label: new TranslatableMarkup("Useful rating"),
+  values: [
+    -1 => new TranslatableMarkup("Not useful"),
+    1 => new TranslatableMarkup("Useful"),
+  ]
+)]
 class UsefulWidget extends VotingApiWidgetBase {
-
   use StringTranslationTrait;
 
   /**