diff --git a/core/modules/content_moderation/content_moderation.routing.yml b/core/modules/content_moderation/content_moderation.routing.yml
index a7167ca..2ee2c47 100644
--- a/core/modules/content_moderation/content_moderation.routing.yml
+++ b/core/modules/content_moderation/content_moderation.routing.yml
@@ -1,7 +1,7 @@
 content_moderation.workflow_type_edit_form:
   path: '/admin/config/workflow/workflows/manage/{workflow}/type/{entity_type_id}'
   defaults:
-    _form: '\Drupal\content_moderation\Form\WorkflowTypeEditForm'
-    _title_callback: '\Drupal\content_moderation\Form\WorkflowTypeEditForm::getTitle'
+    _form: '\Drupal\content_moderation\Form\ContentModerationConfigureEntityTypesForm'
+    _title_callback: '\Drupal\content_moderation\Form\ContentModerationConfigureEntityTypesForm::getTitle'
   requirements:
     _permission: 'administer workflows'
diff --git a/core/modules/content_moderation/src/Form/WorkflowTypeEditForm.php b/core/modules/content_moderation/src/Form/ContentModerationConfigureEntityTypesForm.php
similarity index 99%
rename from core/modules/content_moderation/src/Form/WorkflowTypeEditForm.php
rename to core/modules/content_moderation/src/Form/ContentModerationConfigureEntityTypesForm.php
index b1fe98c..3efcafb 100644
--- a/core/modules/content_moderation/src/Form/WorkflowTypeEditForm.php
+++ b/core/modules/content_moderation/src/Form/ContentModerationConfigureEntityTypesForm.php
@@ -18,7 +18,7 @@
 /**
  * The form for editing entity types associated with a workflow.
  */
-class WorkflowTypeEditForm extends FormBase {
+class ContentModerationConfigureEntityTypesForm extends FormBase {
 
   /**
    * The entity type manager service.
diff --git a/core/modules/content_moderation/src/Form/ContentModerationConfigureForm.php b/core/modules/content_moderation/src/Form/ContentModerationConfigureForm.php
new file mode 100644
index 0000000..04f62fe
--- /dev/null
+++ b/core/modules/content_moderation/src/Form/ContentModerationConfigureForm.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Drupal\content_moderation\Form;
+
+use Drupal\Component\Serialization\Json;
+use Drupal\content_moderation\ModerationInformationInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Drupal\workflows\Plugin\WorkflowTypeConfigureFormBase;
+use Drupal\workflows\WorkflowInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * The content moderation WorkflowType configuration form.
+ *
+ * @see \Drupal\content_moderation\Plugin\WorkflowType\ContentModeration
+ */
+class ContentModerationConfigureForm extends WorkflowTypeConfigureFormBase implements ContainerInjectionInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The moderation info service.
+   *
+   * @var \Drupal\content_moderation\ModerationInformationInterface
+   */
+  protected $moderationInfo;
+
+  /**
+   * The entity type type bundle info service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $entityTypeBundleInfo;
+
+  /**
+   * Create an instance of ContentModerationConfigureForm.
+   */
+  public function __construct(EntityTypeManagerInterface $entityTypeManager, ModerationInformationInterface $moderationInformation, EntityTypeBundleInfoInterface $entityTypeBundleInfo) {
+    $this->entityTypeManager = $entityTypeManager;
+    $this->moderationInfo = $moderationInformation;
+    $this->entityTypeBundleInfo = $entityTypeBundleInfo;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity_type.manager'),
+      $container->get('content_moderation.moderation_information'),
+      $container->get('entity_type.bundle.info')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $workflow = $form_state->getFormObject()->getEntity();
+
+    $header = [
+      'type' => $this->t('Items'),
+      'operations' => $this->t('Operations')
+    ];
+    $form['entity_types_container'] = [
+      '#type' => 'details',
+      '#title' => $this->t('This workflow applies to:'),
+      '#open' => TRUE,
+    ];
+    $form['entity_types_container']['entity_types'] = [
+      '#type' => 'table',
+      '#header' => $header,
+      '#empty' => $this->t('There are no entity types.'),
+    ];
+
+    $entity_types = $this->entityTypeManager->getDefinitions();
+    foreach ($entity_types as $entity_type) {
+      if (!$this->moderationInfo->canModerateEntitiesOfEntityType($entity_type)) {
+        continue;
+      }
+
+      $selected_bundles = [];
+      foreach ($this->entityTypeBundleInfo->getBundleInfo($entity_type->id()) as $bundle_id => $bundle) {
+        if ($this->workflowType->appliesToEntityTypeAndBundle($entity_type->id(), $bundle_id)) {
+          $selected_bundles[$bundle_id] = $bundle['label'];
+        }
+      }
+
+      $form['entity_types_container']['entity_types'][$entity_type->id()] = [
+        'type' => [
+          'label' => ['#markup' => '<strong>' . $this->t('@bundle types', ['@bundle' => $entity_type->getLabel()]) . '</strong>'],
+          'selected' => [
+            '#prefix' => '<br/><span id="selected-' . $entity_type->id() . '">',
+            '#markup' => !empty($selected_bundles) ? implode(', ', $selected_bundles) : $this->t('none'),
+            '#suffix' => '</span>',
+          ],
+        ],
+        'operations' => [
+          '#type' => 'operations',
+          '#links' => [
+            'select' => [
+              'title' => $this->t('Select'),
+              'url' => Url::fromRoute('content_moderation.workflow_type_edit_form', ['workflow' => $workflow->id(), 'entity_type_id' => $entity_type->id()]),
+              'attributes' => [
+                'aria-label' => $this->t('Select'),
+                'class' => ['use-ajax'],
+                'data-dialog-type' => 'modal',
+                'data-dialog-options' => Json::encode([
+                  'width' => 700,
+                ]),
+              ],
+            ],
+          ],
+        ],
+      ];
+    }
+    return $form;
+  }
+
+}
diff --git a/core/modules/content_moderation/src/Form/ContentModerationStateForm.php b/core/modules/content_moderation/src/Form/ContentModerationStateForm.php
new file mode 100644
index 0000000..3ba5f65
--- /dev/null
+++ b/core/modules/content_moderation/src/Form/ContentModerationStateForm.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\content_moderation\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\workflows\Plugin\WorkflowTypeStateFormBase;
+use Drupal\workflows\StateInterface;
+
+/**
+ * The content moderation state form.
+ *
+ * @see \Drupal\content_moderation\Plugin\WorkflowType\ContentModeration
+ */
+class ContentModerationStateForm extends WorkflowTypeStateFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state, StateInterface $state = NULL) {
+    /** @var \Drupal\content_moderation\ContentModerationState $state */
+    $state = $form_state->get('state');
+    $is_required_state = isset($state) ? in_array($state->id(), $this->workflowType->getRequiredStates(), TRUE) : FALSE;
+
+    $form = [];
+    $form['published'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Published'),
+      '#description' => $this->t('When content reaches this state it should be published.'),
+      '#default_value' => isset($state) ? $state->isPublishedState() : FALSE,
+      '#disabled' => $is_required_state,
+    ];
+
+    $form['default_revision'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Default revision'),
+      '#description' => $this->t('When content reaches this state it should be made the default revision; this is implied for published states.'),
+      '#default_value' => isset($state) ? $state->isDefaultRevisionState() : FALSE,
+      '#disabled' => $is_required_state,
+      // @todo Add form #state to force "make default" on when "published" is
+      // on for a state.
+      // @see https://www.drupal.org/node/2645614
+    ];
+    return $form;
+  }
+
+}
diff --git a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php
index 4087387..ad1b4ef 100644
--- a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php
+++ b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php
@@ -8,13 +8,11 @@
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\EntityPublishedInterface;
-use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\content_moderation\ContentModerationState;
-use Drupal\Core\Url;
-use Drupal\workflows\Plugin\WorkflowTypeFormBase;
+use Drupal\workflows\Plugin\WorkflowTypeBase;
 use Drupal\workflows\StateInterface;
 use Drupal\workflows\WorkflowInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -29,9 +27,13 @@
  *     "draft",
  *     "published",
  *   },
+ *   forms = {
+ *     "configure" = "\Drupal\content_moderation\Form\ContentModerationConfigureForm",
+ *     "state" = "\Drupal\content_moderation\Form\ContentModerationStateForm"
+ *   },
  * )
  */
-class ContentModeration extends WorkflowTypeFormBase implements ContainerFactoryPluginInterface {
+class ContentModeration extends WorkflowTypeBase implements ContainerFactoryPluginInterface {
 
   use StringTranslationTrait;
 
@@ -144,35 +146,6 @@ public function workflowStateHasData(WorkflowInterface $workflow, StateInterface
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function buildStateConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, StateInterface $state = NULL) {
-    /** @var \Drupal\content_moderation\ContentModerationState $state */
-    $is_required_state = isset($state) ? in_array($state->id(), $this->getRequiredStates(), TRUE) : FALSE;
-
-    $form = [];
-    $form['published'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Published'),
-      '#description' => $this->t('When content reaches this state it should be published.'),
-      '#default_value' => isset($state) ? $state->isPublishedState() : FALSE,
-      '#disabled' => $is_required_state,
-    ];
-
-    $form['default_revision'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Default revision'),
-      '#description' => $this->t('When content reaches this state it should be made the default revision; this is implied for published states.'),
-      '#default_value' => isset($state) ? $state->isDefaultRevisionState() : FALSE,
-      '#disabled' => $is_required_state,
-      // @todo Add form #state to force "make default" on when "published" is
-      // on for a state.
-      // @see https://www.drupal.org/node/2645614
-    ];
-    return $form;
-  }
-
-  /**
    * Gets the entity types the workflow is applied to.
    *
    * @return string[]
@@ -374,68 +347,4 @@ public function getInitialState(WorkflowInterface $workflow, $entity = NULL) {
     return parent::getInitialState($workflow);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state, WorkflowInterface $workflow = NULL) {
-    $header = [
-      'type' => $this->t('Items'),
-      'operations' => $this->t('Operations')
-    ];
-    $form['entity_types_container'] = [
-      '#type' => 'details',
-      '#title' => $this->t('This workflow applies to:'),
-      '#open' => TRUE,
-    ];
-    $form['entity_types_container']['entity_types'] = [
-      '#type' => 'table',
-      '#header' => $header,
-      '#empty' => $this->t('There are no entity types.'),
-    ];
-
-    $entity_types = $this->entityTypeManager->getDefinitions();
-    foreach ($entity_types as $entity_type) {
-      if (!$this->moderationInfo->canModerateEntitiesOfEntityType($entity_type)) {
-        continue;
-      }
-
-      $selected_bundles = [];
-      foreach ($this->entityTypeBundleInfo->getBundleInfo($entity_type->id()) as $bundle_id => $bundle) {
-        if ($this->appliesToEntityTypeAndBundle($entity_type->id(), $bundle_id)) {
-          $selected_bundles[$bundle_id] = $bundle['label'];
-        }
-      }
-
-      $form['entity_types_container']['entity_types'][$entity_type->id()] = [
-        'type' => [
-          'label' => ['#markup' => '<strong>' . $this->t('@bundle types', ['@bundle' => $entity_type->getLabel()]) . '</strong>'],
-          'selected' => [
-            '#prefix' => '<br/><span id="selected-' . $entity_type->id() . '">',
-            '#markup' => !empty($selected_bundles) ? implode(', ', $selected_bundles) : $this->t('none'),
-            '#suffix' => '</span>',
-          ],
-        ],
-        'operations' => [
-          '#type' => 'operations',
-          '#links' => [
-            'select' => [
-              'title' => $this->t('Select'),
-              'url' => Url::fromRoute('content_moderation.workflow_type_edit_form', ['workflow' => $workflow->id(), 'entity_type_id' => $entity_type->id()]),
-              'attributes' => [
-                'aria-label' => $this->t('Select'),
-                'class' => ['use-ajax'],
-                'data-dialog-type' => 'modal',
-                'data-dialog-options' => Json::encode([
-                  'width' => 700,
-                ]),
-              ],
-            ],
-          ],
-        ],
-      ];
-    }
-
-    return $form;
-  }
-
 }
diff --git a/core/modules/content_moderation/tests/src/Functional/ContentModerationWorkflowTypeTest.php b/core/modules/content_moderation/tests/src/Functional/ContentModerationWorkflowTypeTest.php
index 66065ba..86c658d 100644
--- a/core/modules/content_moderation/tests/src/Functional/ContentModerationWorkflowTypeTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ContentModerationWorkflowTypeTest.php
@@ -62,8 +62,8 @@ public function testNewWorkflow() {
     $this->submitForm([
       'label' => 'Test State',
       'id' => 'test_state',
-      'type_settings[content_moderation][published]' => TRUE,
-      'type_settings[content_moderation][default_revision]' => FALSE,
+      'type_settings[published]' => TRUE,
+      'type_settings[default_revision]' => FALSE,
     ], 'Save');
     $this->assertSession()->pageTextContains('Created Test State state.');
     $this->assertSession()->linkByHrefExists('/admin/config/workflow/workflows/manage/test_workflow/state/test_state/delete');
@@ -78,13 +78,13 @@ public function testNewWorkflow() {
 
     // Ensure that the published settings cannot be changed.
     $this->drupalGet('admin/config/workflow/workflows/manage/test_workflow/state/published');
-    $this->assertSession()->fieldDisabled('type_settings[content_moderation][published]');
-    $this->assertSession()->fieldDisabled('type_settings[content_moderation][default_revision]');
+    $this->assertSession()->fieldDisabled('type_settings[published]');
+    $this->assertSession()->fieldDisabled('type_settings[default_revision]');
 
     // Ensure that the draft settings cannot be changed.
     $this->drupalGet('admin/config/workflow/workflows/manage/test_workflow/state/draft');
-    $this->assertSession()->fieldDisabled('type_settings[content_moderation][published]');
-    $this->assertSession()->fieldDisabled('type_settings[content_moderation][default_revision]');
+    $this->assertSession()->fieldDisabled('type_settings[published]');
+    $this->assertSession()->fieldDisabled('type_settings[default_revision]');
   }
 
 }
diff --git a/core/modules/workflows/src/Annotation/WorkflowType.php b/core/modules/workflows/src/Annotation/WorkflowType.php
index 6e578ed..221f384 100644
--- a/core/modules/workflows/src/Annotation/WorkflowType.php
+++ b/core/modules/workflows/src/Annotation/WorkflowType.php
@@ -50,4 +50,20 @@ class WorkflowType extends Plugin {
    */
   public $required_states = [];
 
+  /**
+   * A list of optional form classes implementing PluginFormInterface.
+   *
+   * Forms which will be used for the workflow UI are 'configure', 'state' and
+   * 'transition'.
+   *
+   * @see \Drupal\Core\Plugin\PluginWithFormsInterface
+   * @see \Drupal\Core\Plugin\PluginFormInterface
+   * @see \Drupal\workflows\Plugin\WorkflowTypeConfigureFormBase
+   * @see \Drupal\workflows\Plugin\WorkflowTypeStateFormBase
+   * @see \Drupal\workflows\Plugin\WorkflowTypeTransitionFormBase
+   *
+   * @var array
+   */
+  public $forms = [];
+
 }
diff --git a/core/modules/workflows/src/Form/WorkflowEditForm.php b/core/modules/workflows/src/Form/WorkflowEditForm.php
index fe59768..4825266 100644
--- a/core/modules/workflows/src/Form/WorkflowEditForm.php
+++ b/core/modules/workflows/src/Form/WorkflowEditForm.php
@@ -3,13 +3,15 @@
 namespace Drupal\workflows\Form;
 
 use Drupal\Core\Form\SubformState;
-use Drupal\workflows\WorkflowTypeFormInterface;
+use Drupal\Core\Plugin\PluginFormFactoryInterface;
 use Drupal\workflows\Entity\Workflow;
 use Drupal\workflows\State;
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\workflows\WorkflowTypeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * The form for editing workflows.
@@ -17,6 +19,32 @@
 class WorkflowEditForm extends EntityForm {
 
   /**
+   * The plugin form factory.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
+   */
+  protected $pluginFormFactory;
+
+  /**
+   * Creates an instance of WorkflowStateEditForm.
+   *
+   * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
+   *   The plugin form factory.
+   */
+  public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
+    $this->pluginFormFactory = $pluginFormFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin_form.factory')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
@@ -24,6 +52,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
     $form['#title'] = $this->t('Edit %label workflow', ['%label' => $workflow->label()]);
 
     $form['label'] = [
@@ -184,12 +213,14 @@ public function form(array $form, FormStateInterface $form_state) {
       '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(),
     ];
 
-    if ($workflow->getTypePlugin() instanceof WorkflowTypeFormInterface) {
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::CONFIGURE_PLUGIN_FORM)) {
       $form['type_settings'] = [
         '#tree' => TRUE,
       ];
       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
-      $form['type_settings'] += $workflow->getTypePlugin()->buildConfigurationForm($form['type_settings'], $subform_state, $workflow);
+      $form['type_settings'] += $this->pluginFormFactory
+        ->createInstance($workflow_type, 'configure')
+        ->buildConfigurationForm($form['type_settings'], $subform_state);
     }
 
     return $form;
@@ -201,9 +232,13 @@ public function form(array $form, FormStateInterface $form_state) {
   public function validateForm(array &$form, FormStateInterface $form_state) {
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
-    if ($workflow->getTypePlugin() instanceof WorkflowTypeFormInterface) {
+    $workflow_type = $workflow->getTypePlugin();
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::CONFIGURE_PLUGIN_FORM)) {
       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
-      $workflow->getTypePlugin()->validateConfigurationForm($form['type_settings'], $subform_state);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, 'configure')
+        ->validateConfigurationForm($form['type_settings'], $subform_state);
     }
   }
 
@@ -213,12 +248,16 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
   public function save(array $form, FormStateInterface $form_state) {
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
-    if ($workflow->getTypePlugin() instanceof WorkflowTypeFormInterface) {
+    $workflow_type = $workflow->getTypePlugin();
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::CONFIGURE_PLUGIN_FORM)) {
       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
-      $workflow->getTypePlugin()->submitConfigurationForm($form['type_settings'], $subform_state);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, 'configure')
+        ->submitConfigurationForm($form['type_settings'], $subform_state);
     }
-    $workflow->save();
 
+    $workflow->save();
     drupal_set_message($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()]));
   }
 
diff --git a/core/modules/workflows/src/Form/WorkflowStateAddForm.php b/core/modules/workflows/src/Form/WorkflowStateAddForm.php
index bfb38bb..322faee 100644
--- a/core/modules/workflows/src/Form/WorkflowStateAddForm.php
+++ b/core/modules/workflows/src/Form/WorkflowStateAddForm.php
@@ -5,6 +5,10 @@
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\SubformState;
+use Drupal\Core\Plugin\PluginFormFactoryInterface;
+use Drupal\workflows\WorkflowTypeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Class WorkflowStateAddForm.
@@ -12,6 +16,32 @@
 class WorkflowStateAddForm extends EntityForm {
 
   /**
+   * The plugin form factory.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
+   */
+  protected $pluginFormFactory;
+
+  /**
+   * Creates an instance of WorkflowStateEditForm.
+   *
+   * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
+   *   The plugin form factory.
+   */
+  public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
+    $this->pluginFormFactory = $pluginFormFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin_form.factory')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getFormId() {
@@ -26,6 +56,8 @@ public function form(array $form, FormStateInterface $form_state) {
 
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->getEntity();
+    $workflow_type = $workflow->getTypePlugin();
+
     $form['label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Label'),
@@ -42,11 +74,15 @@ public function form(array $form, FormStateInterface $form_state) {
       ],
     ];
 
-    // Add additional form fields from the workflow type plugin.
-    $form['type_settings'] = [
-      $workflow->get('type') => $workflow->getTypePlugin()->buildStateConfigurationForm($form_state, $workflow),
-      '#tree' => TRUE,
-    ];
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::STATE_PLUGIN_FORM)) {
+      $form['type_settings'] = [
+        '#tree' => TRUE,
+      ];
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $form['type_settings'] += $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::STATE_PLUGIN_FORM)
+        ->buildConfigurationForm($form['type_settings'], $subform_state);
+    }
 
     return $form;
   }
@@ -81,17 +117,29 @@ public function exists($state_id) {
   protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $entity */
     $values = $form_state->getValues();
+    $type_plugin = $entity->getTypePlugin();
 
     // Replicate the validation that Workflow::addState() does internally as the
     // form values have not been validated at this point.
-    if (!$entity->getTypePlugin()->hasState($values['id']) && !preg_match('/[^a-z0-9_]+/', $values['id'])) {
-      $entity->getTypePlugin()->addState($values['id'], $values['label']);
-      if (isset($values['type_settings'])) {
-        $configuration = $entity->getTypePlugin()->getConfiguration();
-        // @todo move to submitStateConfigurationForm. #2849827.
-        $configuration['states'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
-        $entity->set('type_settings', $configuration);
-      }
+    if (!$type_plugin->hasState($values['id']) && !preg_match('/[^a-z0-9_]+/', $values['id'])) {
+      $type_plugin->addState($values['id'], $values['label']);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    parent::validateForm($form, $form_state);
+    /** @var \Drupal\workflows\WorkflowTypeInterface $workflow_type */
+    $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::STATE_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::STATE_PLUGIN_FORM)
+        ->validateConfigurationForm($form['type_settings'], $subform_state);
     }
   }
 
@@ -101,6 +149,17 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
   public function save(array $form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
+    $state = $workflow_type->getState($form_state->getValue('id'));
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::STATE_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('state', $state);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::STATE_PLUGIN_FORM)
+        ->submitConfigurationForm($form['type_settings'], $subform_state);
+    }
+
     $workflow->save();
     drupal_set_message($this->t('Created %label state.', [
       '%label' => $workflow->getTypePlugin()->getState($form_state->getValue('id'))->label(),
diff --git a/core/modules/workflows/src/Form/WorkflowStateEditForm.php b/core/modules/workflows/src/Form/WorkflowStateEditForm.php
index e8f2a55..a219fe3 100644
--- a/core/modules/workflows/src/Form/WorkflowStateEditForm.php
+++ b/core/modules/workflows/src/Form/WorkflowStateEditForm.php
@@ -5,7 +5,11 @@
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\SubformState;
+use Drupal\Core\Plugin\PluginFormFactoryInterface;
 use Drupal\Core\Url;
+use Drupal\workflows\WorkflowTypeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Class WorkflowStateEditForm.
@@ -20,6 +24,32 @@ class WorkflowStateEditForm extends EntityForm {
   protected $stateId;
 
   /**
+   * The plugin form factory.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
+   */
+  protected $pluginFormFactory;
+
+  /**
+   * Creates an instance of WorkflowStateEditForm.
+   *
+   * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
+   *   The plugin form factory.
+   */
+  public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
+    $this->pluginFormFactory = $pluginFormFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin_form.factory')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getFormId() {
@@ -42,7 +72,9 @@ public function form(array $form, FormStateInterface $form_state) {
 
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->getEntity();
+    $workflow_type = $workflow->getTypePlugin();
     $state = $workflow->getTypePlugin()->getState($this->stateId);
+
     $form['label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Label'),
@@ -62,10 +94,16 @@ public function form(array $form, FormStateInterface $form_state) {
     ];
 
     // Add additional form fields from the workflow type plugin.
-    $form['type_settings'] = [
-      $workflow->get('type') => $workflow->getTypePlugin()->buildStateConfigurationForm($form_state, $workflow, $state),
-      '#tree' => TRUE,
-    ];
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::STATE_PLUGIN_FORM)) {
+      $form['type_settings'] = [
+        '#tree' => TRUE,
+      ];
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('state', $state);
+      $form['type_settings'] += $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::STATE_PLUGIN_FORM)
+        ->buildConfigurationForm($form['type_settings'], $subform_state);
+    }
 
     $header = [
       'label' => $this->t('Transition'),
@@ -125,10 +163,23 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
     /** @var \Drupal\workflows\WorkflowInterface $entity */
     $values = $form_state->getValues();
     $entity->getTypePlugin()->setStateLabel($values['id'], $values['label']);
-    if (isset($values['type_settings'])) {
-      $configuration = $entity->getTypePlugin()->getConfiguration();
-      $configuration['states'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
-      $entity->set('type_settings', $configuration);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    parent::validateForm($form, $form_state);
+    /** @var \Drupal\workflows\WorkflowTypeInterface $workflow_type */
+    $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::STATE_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('state', $workflow_type->getState($this->stateId));
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::STATE_PLUGIN_FORM)
+        ->validateConfigurationForm($form['type_settings'], $subform_state);
     }
   }
 
@@ -138,6 +189,16 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
   public function save(array $form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::STATE_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('state', $workflow_type->getState($this->stateId));
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::STATE_PLUGIN_FORM)
+        ->submitConfigurationForm($form['type_settings'], $subform_state);
+    }
+
     $workflow->save();
     drupal_set_message($this->t('Saved %label state.', [
       '%label' => $workflow->getTypePlugin()->getState($this->stateId)->label(),
diff --git a/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php b/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php
index 2ffeaff..78a173f 100644
--- a/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php
+++ b/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php
@@ -5,7 +5,11 @@
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\SubformState;
+use Drupal\Core\Plugin\PluginFormFactoryInterface;
 use Drupal\workflows\State;
+use Drupal\workflows\WorkflowTypeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Class WorkflowTransitionAddForm.
@@ -13,6 +17,32 @@
 class WorkflowTransitionAddForm extends EntityForm {
 
   /**
+   * The plugin form factory.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
+   */
+  protected $pluginFormFactory;
+
+  /**
+   * Creates an instance of WorkflowStateEditForm.
+   *
+   * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
+   *   The plugin form factory.
+   */
+  public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
+    $this->pluginFormFactory = $pluginFormFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin_form.factory')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getFormId() {
@@ -27,6 +57,8 @@ public function form(array $form, FormStateInterface $form_state) {
 
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->getEntity();
+    $workflow_type = $workflow->getTypePlugin();
+
     $form['label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Label'),
@@ -62,10 +94,15 @@ public function form(array $form, FormStateInterface $form_state) {
     ];
 
     // Add additional form fields from the workflow type plugin.
-    $form['type_settings'] = [
-      $workflow->get('type') => $workflow->getTypePlugin()->buildTransitionConfigurationForm($form_state, $workflow),
-      '#tree' => TRUE,
-    ];
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)) {
+      $form['type_settings'] = [
+        '#tree' => TRUE,
+      ];
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $form['type_settings'] += $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)
+        ->buildConfigurationForm($form['type_settings'], $subform_state);
+    }
 
     return $form;
   }
@@ -105,20 +142,16 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
     /** @var \Drupal\workflows\WorkflowInterface $entity */
     $values = $form_state->getValues();
     $entity->getTypePlugin()->addTransition($values['id'], $values['label'], array_filter($values['from']), $values['to']);
-    if (isset($values['type_settings'])) {
-      $configuration = $entity->getTypePlugin()->getConfiguration();
-      $configuration['transitions'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
-      $entity->set('type_settings', $configuration);
-    }
   }
 
-
   /**
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->getEntity();
+    $workflow_type = $workflow->getTypePlugin();
+
     $values = $form_state->getValues();
     foreach (array_filter($values['from']) as $from_state_id) {
       if ($workflow->getTypePlugin()->hasTransitionFromStateToState($from_state_id, $values['to'])) {
@@ -128,6 +161,13 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
         ]));
       }
     }
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)
+        ->validateConfigurationForm($form['type_settings'], $subform_state);
+    }
   }
 
   /**
@@ -136,6 +176,17 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
   public function save(array $form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
+    $transition = $workflow_type->getTransition($form_state->getValue('id'));
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('transition', $transition);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)
+        ->submitConfigurationForm($form['type_settings'], $subform_state);
+    }
+
     $workflow->save();
     drupal_set_message($this->t('Created %label transition.', [
       '%label' => $form_state->getValue('label'),
diff --git a/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php b/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php
index f776e35..92db190 100644
--- a/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php
+++ b/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php
@@ -5,8 +5,12 @@
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\SubformState;
+use Drupal\Core\Plugin\PluginFormFactoryInterface;
 use Drupal\Core\Url;
 use Drupal\workflows\State;
+use Drupal\workflows\WorkflowTypeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Class WorkflowTransitionEditForm.
@@ -21,6 +25,32 @@ class WorkflowTransitionEditForm extends EntityForm {
   protected $transitionId;
 
   /**
+   * The plugin form factory.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
+   */
+  protected $pluginFormFactory;
+
+  /**
+   * Creates an instance of WorkflowStateEditForm.
+   *
+   * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
+   *   The plugin form factory.
+   */
+  public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
+    $this->pluginFormFactory = $pluginFormFactory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('plugin_form.factory')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getFormId() {
@@ -43,7 +73,9 @@ public function form(array $form, FormStateInterface $form_state) {
 
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->getEntity();
+    $workflow_type = $workflow->getTypePlugin();
     $transition = $workflow->getTypePlugin()->getTransition($this->transitionId);
+
     $form['label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Label'),
@@ -78,10 +110,16 @@ public function form(array $form, FormStateInterface $form_state) {
     ];
 
     // Add additional form fields from the workflow type plugin.
-    $form['type_settings'] = [
-      $workflow->get('type') => $workflow->getTypePlugin()->buildTransitionConfigurationForm($form_state, $workflow, $transition),
-      '#tree' => TRUE,
-    ];
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)) {
+      $form['type_settings'] = [
+        '#tree' => TRUE,
+      ];
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('transition', $transition);
+      $form['type_settings'] += $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)
+        ->buildConfigurationForm($form['type_settings'], $subform_state);
+    }
 
     return $form;
   }
@@ -92,11 +130,14 @@ public function form(array $form, FormStateInterface $form_state) {
   public function validateForm(array &$form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->getEntity();
+    $workflow_type = $workflow->getTypePlugin();
+    $transition = $workflow_type->getTransition($this->transitionId);
+
     $values = $form_state->getValues();
     foreach (array_filter($values['from']) as $from_state_id) {
-      if ($workflow->getTypePlugin()->hasTransitionFromStateToState($from_state_id, $values['to'])) {
-        $transition = $workflow->getTypePlugin()->getTransitionFromStateToState($from_state_id, $values['to']);
-        if ($transition->id() !== $values['id']) {
+      if ($workflow_type->hasTransitionFromStateToState($from_state_id, $values['to'])) {
+        $existing_transition = $workflow_type->getTransitionFromStateToState($from_state_id, $values['to']);
+        if ($existing_transition->id() !== $values['id']) {
           $form_state->setErrorByName('from][' . $from_state_id, $this->t('The transition from %from to %to already exists.', [
             '%from' => $workflow->getTypePlugin()->getState($from_state_id)->label(),
             '%to' => $workflow->getTypePlugin()->getState($values['to'])->label(),
@@ -104,6 +145,14 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
         }
       }
     }
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('transition', $transition);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)
+        ->validateConfigurationForm($form['type_settings'], $subform_state);
+    }
   }
 
   /**
@@ -128,11 +177,6 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
     $form_state->set('created_transition', FALSE);
     $entity->getTypePlugin()->setTransitionLabel($values['id'], $values['label']);
     $entity->getTypePlugin()->setTransitionFromStates($values['id'], array_filter($values['from']));
-    if (isset($values['type_settings'])) {
-      $configuration = $entity->getTypePlugin()->getConfiguration();
-      $configuration['transitions'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
-      $entity->set('type_settings', $configuration);
-    }
   }
 
   /**
@@ -141,6 +185,17 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
   public function save(array $form, FormStateInterface $form_state) {
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
+    $workflow_type = $workflow->getTypePlugin();
+    $transition = $workflow_type->getTransition($this->transitionId);
+
+    if ($workflow_type->hasFormClass(WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $subform_state->set('transition', $transition);
+      $this->pluginFormFactory
+        ->createInstance($workflow_type, WorkflowTypeInterface::TRANSITION_PLUGIN_FORM)
+        ->submitConfigurationForm($form['type_settings'], $subform_state);
+    }
+
     $workflow->save();
     drupal_set_message($this->t('Saved %label transition.', [
       '%label' => $workflow->getTypePlugin()->getTransition($this->transitionId)->label(),
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
index 440eb56..4394a29 100644
--- a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Plugin\PluginBase;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginWithFormsTrait;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\workflows\State;
 use Drupal\workflows\StateInterface;
@@ -24,6 +25,8 @@
  */
 abstract class WorkflowTypeBase extends PluginBase implements WorkflowTypeInterface {
 
+  use PluginWithFormsTrait;
+
   /**
    * A regex for matching a valid state/transition machine name.
    */
@@ -92,20 +95,6 @@ public function decorateTransition(TransitionInterface $transition) {
   /**
    * {@inheritdoc}
    */
-  public function buildStateConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, StateInterface $state = NULL) {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildTransitionConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, TransitionInterface $transition = NULL) {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getConfiguration() {
     return $this->configuration;
   }
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeConfigureFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeConfigureFormBase.php
new file mode 100644
index 0000000..a9ee723
--- /dev/null
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeConfigureFormBase.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Drupal\workflows\Plugin;
+
+use Drupal\Component\Plugin\PluginAwareInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\workflows\WorkflowInterface;
+
+/**
+ * A base class for workflow type configuration forms.
+ */
+abstract class WorkflowTypeConfigureFormBase implements PluginFormInterface, PluginAwareInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * The workflow type.
+   *
+   * @var \Drupal\workflows\WorkflowTypeInterface
+   */
+  protected $workflowType;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setPlugin(PluginInspectionInterface $plugin) {
+    $this->workflowType = $plugin;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeFormBase.php
deleted file mode 100644
index 942c2d6..0000000
--- a/core/modules/workflows/src/Plugin/WorkflowTypeFormBase.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Drupal\workflows\Plugin;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\workflows\WorkflowTypeFormInterface;
-
-/**
- * Provides a base class for configurable workflow types.
- *
- * @see \Drupal\workflows\WorkflowTypeFormInterface
- * @see \Drupal\workflows\WorkflowTypeInterface
- * @see \Drupal\workflows\Plugin\WorkflowTypeBase
- * @see plugin_api
- */
-abstract class WorkflowTypeFormBase extends WorkflowTypeBase implements WorkflowTypeFormInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
-  }
-
-}
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeStateFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeStateFormBase.php
new file mode 100644
index 0000000..5d328d7
--- /dev/null
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeStateFormBase.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\workflows\Plugin;
+
+use Drupal\Component\Plugin\PluginAwareInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\workflows\StateInterface;
+
+/**
+ * A base class for workflow type state forms.
+ */
+abstract class WorkflowTypeStateFormBase implements PluginFormInterface, PluginAwareInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * The workflow type.
+   *
+   * @var \Drupal\workflows\WorkflowTypeInterface
+   */
+  protected $workflowType;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setPlugin(PluginInspectionInterface $plugin) {
+    $this->workflowType = $plugin;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $values = $form_state->getValues();
+    $state = $form_state->get('state');
+    $configuration = $this->workflowType->getConfiguration();
+    $configuration['states'][$state->id()] = $values + $configuration['states'][$state->id()];
+    $this->workflowType->setConfiguration($configuration);
+  }
+
+}
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeTransitionFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeTransitionFormBase.php
new file mode 100644
index 0000000..c979a67
--- /dev/null
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeTransitionFormBase.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\workflows\Plugin;
+
+use Drupal\Component\Plugin\PluginAwareInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\workflows\TransitionInterface;
+
+/**
+ * A base class for workflow type transition forms.
+ */
+abstract class WorkflowTypeTransitionFormBase implements PluginFormInterface, PluginAwareInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * The workflow type.
+   *
+   * @var \Drupal\workflows\WorkflowTypeInterface
+   */
+  protected $workflowType;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setPlugin(PluginInspectionInterface $plugin) {
+    $this->workflowType = $plugin;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $values = $form_state->getValues();
+    $transition = $form_state->get('transition');
+    $configuration = $this->workflowType->getConfiguration();
+    $configuration['transitions'][$transition->id()] = $values + $configuration['transitions'][$transition->id()];
+    $this->workflowType->setConfiguration($configuration);
+  }
+
+}
diff --git a/core/modules/workflows/src/WorkflowTypeFormInterface.php b/core/modules/workflows/src/WorkflowTypeFormInterface.php
deleted file mode 100644
index 7da4bd9..0000000
--- a/core/modules/workflows/src/WorkflowTypeFormInterface.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-namespace Drupal\workflows;
-
-use Drupal\Core\Plugin\PluginFormInterface;
-
-/**
- * Defines the interface for configurable workflow types.
- *
- * @see \Drupal\workflows\Plugin\WorkflowTypeFormBase
- * @see \Drupal\workflows\WorkflowTypeInterface
- * @see \Drupal\Core\Plugin\PluginFormInterface
- * @see plugin_api
- */
-interface WorkflowTypeFormInterface extends PluginFormInterface, WorkflowTypeInterface {
-}
diff --git a/core/modules/workflows/src/WorkflowTypeInterface.php b/core/modules/workflows/src/WorkflowTypeInterface.php
index 6ff8832..00700b9 100644
--- a/core/modules/workflows/src/WorkflowTypeInterface.php
+++ b/core/modules/workflows/src/WorkflowTypeInterface.php
@@ -4,8 +4,8 @@
 
 use Drupal\Component\Plugin\ConfigurablePluginInterface;
 use Drupal\Component\Plugin\DerivativeInspectionInterface;
-use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\PluginWithFormsInterface;
 use Drupal\Core\Session\AccountInterface;
 
 /**
@@ -15,7 +15,22 @@
  *   The workflow system is currently experimental and should only be leveraged
  *   by experimental modules and development releases of contributed modules.
  */
-interface WorkflowTypeInterface extends PluginInspectionInterface, DerivativeInspectionInterface, ConfigurablePluginInterface {
+interface WorkflowTypeInterface extends PluginWithFormsInterface, DerivativeInspectionInterface, ConfigurablePluginInterface {
+
+  /**
+   * The ID of the global workflow plugin form.
+   */
+  const CONFIGURE_PLUGIN_FORM = 'configure';
+
+  /**
+   * The ID of the state plugin form.
+   */
+  const STATE_PLUGIN_FORM = 'state';
+
+  /**
+   * The ID of the transition plugin form.
+   */
+  const TRANSITION_PLUGIN_FORM = 'transition';
 
   /**
    * Initializes a workflow.
@@ -121,45 +136,6 @@ public function decorateTransition(TransitionInterface $transition);
   public function getInitialState(WorkflowInterface $workflow);
 
   /**
-   * Builds a form to be added to the Workflow state edit form.
-   *
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state.
-   * @param \Drupal\workflows\WorkflowInterface $workflow
-   *   The workflow the state is attached to.
-   * @param \Drupal\workflows\StateInterface|null $state
-   *   The workflow state being edited. If NULL, a new state is being added.
-   *
-   * @return array
-   *   Form elements to add to a workflow state form for customisations to the
-   *   workflow.
-   *
-   * @see \Drupal\workflows\Form\WorkflowStateAddForm::form()
-   * @see \Drupal\workflows\Form\WorkflowStateEditForm::form()
-   */
-  public function buildStateConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, StateInterface $state = NULL);
-
-  /**
-   * Builds a form to be added to the Workflow transition edit form.
-   *
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state.
-   * @param \Drupal\workflows\WorkflowInterface $workflow
-   *   The workflow the state is attached to.
-   * @param \Drupal\workflows\TransitionInterface|null $transition
-   *   The workflow transition being edited. If NULL, a new transition is being
-   *   added.
-   *
-   * @return array
-   *   Form elements to add to a workflow transition form for customisations to
-   *   the workflow.
-   *
-   * @see \Drupal\workflows\Form\WorkflowTransitionAddForm::form()
-   * @see \Drupal\workflows\Form\WorkflowTransitionEditForm::form()
-   */
-  public function buildTransitionConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, TransitionInterface $transition = NULL);
-
-  /**
    * Gets the required states of workflow type.
    *
    * This are usually configured in the workflow type annotation.
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeConfigureForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeConfigureForm.php
new file mode 100644
index 0000000..0fe5bd8
--- /dev/null
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeConfigureForm.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\workflow_type_test\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\workflows\Plugin\WorkflowTypeConfigureFormBase;
+use Drupal\workflows\WorkflowInterface;
+
+/**
+ * Form to configure the complex test workflow type.
+ *
+ * @see \Drupal\workflow_type_test\Plugin\WorkflowType\ComplexTestType
+ */
+class ComplexTestTypeConfigureForm extends WorkflowTypeConfigureFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $type_configuration = $this->workflowType->getConfiguration();
+    $form['example_setting'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Example global workflow setting'),
+      '#description' => $this->t('Extra information added to the workflow'),
+      '#default_value' => $type_configuration['example_setting'],
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $type_configuration = $this->workflowType->getConfiguration();
+    $type_configuration['example_setting'] = $form_state->getValue('example_setting');
+    $this->workflowType->setConfiguration($type_configuration);
+  }
+
+}
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php
new file mode 100644
index 0000000..a76e67d
--- /dev/null
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\workflow_type_test\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\workflows\Plugin\WorkflowTypeStateFormBase;
+use Drupal\workflows\StateInterface;
+
+/**
+ * Form to configure the complex test workflow states.
+ *
+ * @see \Drupal\workflow_type_test\Plugin\WorkflowType\ComplexTestType
+ */
+class ComplexTestTypeStateForm extends WorkflowTypeStateFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    /** @var \Drupal\workflow_type_test\DecoratedState $state */
+    $state = $form_state->get('state');
+    $form = [];
+    $form['extra'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Extra'),
+      '#description' => $this->t('Extra information added to state'),
+      '#default_value' => isset($state) ? $state->getExtra() : FALSE,
+    ];
+    return $form;
+  }
+
+}
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php
new file mode 100644
index 0000000..0b6a8b9
--- /dev/null
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\workflow_type_test\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\workflows\Plugin\WorkflowTypeTransitionFormBase;
+use Drupal\workflows\TransitionInterface;
+
+/**
+ * Form to configure the complex test workflow states.
+ *
+ * @see \Drupal\workflow_type_test\Plugin\WorkflowType\ComplexTestType
+ */
+class ComplexTestTypeTransitionForm extends WorkflowTypeTransitionFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    /** @var \Drupal\workflow_type_test\DecoratedTransition $transition */
+    $transition = $form_state->get('transition');
+    $form = [];
+    $form['extra'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Extra'),
+      '#description' => $this->t('Extra information added to transition'),
+      '#default_value' => isset($transition) ? $transition->getExtra() : FALSE,
+    ];
+    return $form;
+  }
+
+}
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php
index 43d976c..a365c41 100644
--- a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php
@@ -2,12 +2,10 @@
 
 namespace Drupal\workflow_type_test\Plugin\WorkflowType;
 
-use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\workflows\Plugin\WorkflowTypeFormBase;
+use Drupal\workflows\Plugin\WorkflowTypeBase;
 use Drupal\workflows\StateInterface;
 use Drupal\workflows\TransitionInterface;
-use Drupal\workflows\WorkflowInterface;
 use Drupal\workflow_type_test\DecoratedState;
 use Drupal\workflow_type_test\DecoratedTransition;
 
@@ -17,9 +15,14 @@
  * @WorkflowType(
  *   id = "workflow_type_complex_test",
  *   label = @Translation("Workflow Type Complex Test"),
+ *   forms = {
+ *     "configure" = "\Drupal\workflow_type_test\Form\ComplexTestTypeConfigureForm",
+ *     "state" = "\Drupal\workflow_type_test\Form\ComplexTestTypeStateForm",
+ *     "transition" = "\Drupal\workflow_type_test\Form\ComplexTestTypeTransitionForm",
+ *   }
  * )
  */
-class ComplexTestType extends WorkflowTypeFormBase {
+class ComplexTestType extends WorkflowTypeBase {
 
   use StringTranslationTrait;
 
@@ -54,36 +57,6 @@ public function decorateTransition(TransitionInterface $transition) {
   /**
    * {@inheritdoc}
    */
-  public function buildStateConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, StateInterface $state = NULL) {
-    /** @var \Drupal\workflow_type_test\DecoratedState $state */
-    $form = [];
-    $form['extra'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Extra'),
-      '#description' => $this->t('Extra information added to state'),
-      '#default_value' => isset($state) ? $state->getExtra() : FALSE,
-    ];
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildTransitionConfigurationForm(FormStateInterface $form_state, WorkflowInterface $workflow, TransitionInterface $transition = NULL) {
-    /** @var \Drupal\workflow_type_test\DecoratedTransition $transition */
-    $form = [];
-    $form['extra'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Extra'),
-      '#description' => $this->t('Extra information added to transition'),
-      '#default_value' => isset($transition) ? $transition->getExtra() : FALSE,
-    ];
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function onDependencyRemoval(array $dependencies) {
     // Always return TRUE to allow the logic in
     // \Drupal\workflows\Entity\Workflow::onDependencyRemoval() to be tested.
@@ -99,24 +72,4 @@ public function defaultConfiguration() {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $form['example_setting'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Example global workflow setting'),
-      '#description' => $this->t('Extra information added to the workflow'),
-      '#default_value' => $this->configuration['example_setting'],
-    ];
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
-    $this->configuration['example_setting'] = $form_state->getValue('example_setting');
-  }
-
 }
diff --git a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
index 3bbe192..308d6fe 100644
--- a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
+++ b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
@@ -312,12 +312,12 @@ public function testWorkflowDecoration() {
     // Add additional state information when editing.
     $this->drupalGet('admin/config/workflow/workflows/manage/test/state/published');
     $this->assertSession()->pageTextContains('Extra information added to state');
-    $this->submitForm(['type_settings[workflow_type_complex_test][extra]' => 'Extra state information'], 'Save');
+    $this->submitForm(['type_settings[extra]' => 'Extra state information'], 'Save');
 
     // Add additional transition information when editing.
     $this->drupalGet('admin/config/workflow/workflows/manage/test/transition/publish');
     $this->assertSession()->pageTextContains('Extra information added to transition');
-    $this->submitForm(['type_settings[workflow_type_complex_test][extra]' => 'Extra transition information'], 'Save');
+    $this->submitForm(['type_settings[extra]' => 'Extra transition information'], 'Save');
 
     $workflow_storage = $this->container->get('entity_type.manager')->getStorage('workflow');
     /** @var \Drupal\workflows\WorkflowInterface $workflow */
@@ -328,12 +328,12 @@ public function testWorkflowDecoration() {
     // Add additional state information when adding.
     $this->drupalGet('admin/config/workflow/workflows/manage/test/add_state');
     $this->assertSession()->pageTextContains('Extra information added to state');
-    $this->submitForm(['label' => 'Draft', 'id' => 'draft', 'type_settings[workflow_type_complex_test][extra]' => 'Extra state information on add'], 'Save');
+    $this->submitForm(['label' => 'Draft', 'id' => 'draft', 'type_settings[extra]' => 'Extra state information on add'], 'Save');
 
     // Add additional transition information when adding.
     $this->drupalGet('admin/config/workflow/workflows/manage/test/add_transition');
     $this->assertSession()->pageTextContains('Extra information added to transition');
-    $this->submitForm(['id' => 'draft_published', 'label' => 'Publish', 'from[draft]' => 'draft', 'to' => 'published', 'type_settings[workflow_type_complex_test][extra]' => 'Extra transition information on add'], 'Save');
+    $this->submitForm(['id' => 'draft_published', 'label' => 'Publish', 'from[draft]' => 'draft', 'to' => 'published', 'type_settings[extra]' => 'Extra transition information on add'], 'Save');
 
     $workflow = $workflow_storage->loadUnchanged('test');
     $this->assertEquals('Extra state information on add', $workflow->getTypePlugin()->getState('draft')->getExtra());
