diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/field_type/LinkItem.php b/core/modules/link/lib/Drupal/link/Plugin/field/field_type/LinkItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..998e60f33a586f9e83e41c2bc0f79ac53a623afa
--- /dev/null
+++ b/core/modules/link/lib/Drupal/link/Plugin/field/field_type/LinkItem.php
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\email\Plugin\field\field_type\LinkItem.
+ */
+
+namespace Drupal\link\Plugin\field\field_type;
+
+use Drupal\Core\Entity\Annotation\FieldType;
+use Drupal\Core\Annotation\Translation;
+use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;
+use Drupal\field\Plugin\Core\Entity\Field;
+
+/**
+ * Plugin implementation of the 'link' field type.
+ *
+ * @FieldType(
+ *   id = "link",
+ *   label = @Translation("Link"),
+ *   description = @Translation("Stores a URL string, optional varchar link text, and optional blob of attributes to assemble a link."),
+ *   instance_settings = {
+ *     "title" = "1"
+ *   },
+ *   default_widget = "link_default",
+ *   default_formatter = "link"
+ * )
+ */
+class LinkItem extends ConfigFieldItemBase {
+
+  /**
+   * Definitions of the contained properties.
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions['url'] = array(
+        'type' => 'uri',
+        'label' => t('URL'),
+      );
+      static::$propertyDefinitions['title'] = array(
+        'type' => 'string',
+        'label' => t('Link text'),
+      );
+      static::$propertyDefinitions['attributes'] = array(
+        'type' => 'map',
+        'label' => t('Attributes'),
+      );
+    }
+    return static::$propertyDefinitions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(Field $field) {
+    return array(
+      'columns' => array(
+        'url' => array(
+          'description' => 'The URL of the link.',
+          'type' => 'varchar',
+          'length' => 2048,
+          'not null' => FALSE,
+        ),
+        'title' => array(
+          'description' => 'The link text.',
+          'type' => 'varchar',
+          'length' => 255,
+          'not null' => FALSE,
+        ),
+        'attributes' => array(
+          'description' => 'Serialized array of attributes for the link.',
+          'type' => 'blob',
+          'size' => 'big',
+          'not null' => FALSE,
+          'serialize' => TRUE,
+        ),
+      ),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function instanceSettingsForm(array $form, array &$form_state) {
+    $element = array();
+
+    $element['title'] = array(
+      '#type' => 'radios',
+      '#title' => t('Allow link text'),
+      '#default_value' => $this->getFieldDefinition()->getFieldSetting('title'),
+      '#options' => array(
+        DRUPAL_DISABLED => t('Disabled'),
+        DRUPAL_OPTIONAL => t('Optional'),
+        DRUPAL_REQUIRED => t('Required'),
+      ),
+    );
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave() {
+    $item = $this->getValue();
+    // Trim any spaces around the URL and link text.
+    $this->url = trim($this->url);
+    $this->title = trim($this->title);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    $value = $this->get('url')->getValue();
+    return $value === NULL || $value === '';
+  }
+
+}
diff --git a/core/modules/link/lib/Drupal/link/Type/LinkItem.php b/core/modules/link/lib/Drupal/link/Type/LinkItem.php
deleted file mode 100644
index d41d3bef1885db34d9aca87878d84642904c85f3..0000000000000000000000000000000000000000
--- a/core/modules/link/lib/Drupal/link/Type/LinkItem.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Type\LinkItem.
- */
-
-namespace Drupal\link\Type;
-
-use Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem;
-
-/**
- * Defines the 'link_field' entity field item.
- */
-class LinkItem extends LegacyConfigFieldItem {
-
-  /**
-   * Property definitions of the contained properties.
-   *
-   * @see self::getPropertyDefinitions()
-   *
-   * @var array
-   */
-  static $propertyDefinitions;
-
-  /**
-   * Implements ComplexDataInterface::getPropertyDefinitions().
-   */
-  public function getPropertyDefinitions() {
-
-    if (!isset(self::$propertyDefinitions)) {
-      self::$propertyDefinitions['url'] = array(
-        'type' => 'uri',
-        'label' => t('URL'),
-      );
-      self::$propertyDefinitions['title'] = array(
-        'type' => 'string',
-        'label' => t('Link text'),
-      );
-      self::$propertyDefinitions['attributes'] = array(
-        'type' => 'map',
-        'label' => t('Attributes'),
-      );
-    }
-    return self::$propertyDefinitions;
-  }
-}
diff --git a/core/modules/link/link.install b/core/modules/link/link.install
deleted file mode 100644
index 3714d356a42b43ff5af561009b89449b7de5052a..0000000000000000000000000000000000000000
--- a/core/modules/link/link.install
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains install, update, and uninstall functionality for the Link module.
- */
-
-/**
- * Implements hook_field_schema().
- */
-function link_field_schema($field) {
-  $schema['columns']['url'] = array(
-    'description' => 'The URL of the link.',
-    'type' => 'varchar',
-    'length' => 2048,
-    'not null' => FALSE,
-  );
-  $schema['columns']['title'] = array(
-    'description' => 'The link text.',
-    'type' => 'varchar',
-    'length' => 255,
-    'not null' => FALSE,
-  );
-  $schema['columns']['attributes'] = array(
-    'description' => 'Serialized array of attributes for the link.',
-    'type' => 'blob',
-    'size' => 'big',
-    'not null' => FALSE,
-    'serialize' => TRUE,
-  );
-  return $schema;
-}
diff --git a/core/modules/link/link.module b/core/modules/link/link.module
index 61066dd72595ebc03ce72799a8e5db72ff728a3c..82840b31769a8b5f1b6f8696be3a737429a98fc7 100644
--- a/core/modules/link/link.module
+++ b/core/modules/link/link.module
@@ -5,8 +5,6 @@
  * Defines simple link field types.
  */
 
-use Drupal\Core\Entity\EntityInterface;
-
 /**
  * Implements hook_help().
  */
@@ -20,58 +18,6 @@ function link_help($path, $arg) {
   }
 }
 
-/**
- * Implements hook_field_info().
- */
-function link_field_info() {
-  $types['link'] = array(
-    'label' => t('Link'),
-    'description' => t('Stores a URL string, optional varchar link text, and optional blob of attributes to assemble a link.'),
-    'instance_settings' => array(
-      'title' => DRUPAL_OPTIONAL,
-    ),
-    'default_widget' => 'link_default',
-    'default_formatter' => 'link',
-    'class' => '\Drupal\link\Type\LinkItem',
-  );
-  return $types;
-}
-
-/**
- * Implements hook_field_instance_settings_form().
- */
-function link_field_instance_settings_form($field, $instance) {
-  $form['title'] = array(
-    '#type' => 'radios',
-    '#title' => t('Allow link text'),
-    '#default_value' => isset($instance['settings']['title']) ? $instance['settings']['title'] : DRUPAL_OPTIONAL,
-    '#options' => array(
-      DRUPAL_DISABLED => t('Disabled'),
-      DRUPAL_OPTIONAL => t('Optional'),
-      DRUPAL_REQUIRED => t('Required'),
-    ),
-  );
-  return $form;
-}
-
-/**
- * Implements hook_field_is_empty().
- */
-function link_field_is_empty($item, $field_type) {
-  return !isset($item['url']) || $item['url'] === '';
-}
-
-/**
- * Implements hook_field_presave().
- */
-function link_field_presave(EntityInterface $entity, $field, $instance, $langcode, &$items) {
-  foreach ($items as $delta => &$item) {
-    // Trim any spaces around the URL and link text.
-    $item['url'] = trim($item['url']);
-    $item['title'] = trim($item['title']);
-  }
-}
-
 /**
  * Implements hook_theme().
  */