diff --git a/src/Entity/MediaBundle.php b/src/Entity/MediaBundle.php
index 8833f82..d8ad3d7 100644
--- a/src/Entity/MediaBundle.php
+++ b/src/Entity/MediaBundle.php
@@ -2,8 +2,9 @@
 
 namespace Drupal\media_entity\Entity;
 
-use Drupal\Core\Entity\EntityDescriptionInterface;
 use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
+use Drupal\Core\Entity\EntityDescriptionInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
 use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection;
 use Drupal\media_entity\MediaBundleInterface;
@@ -121,7 +122,7 @@ class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface
   /**
    * Default status of this media bundle.
    *
-   * @var array
+   * @var bool
    */
   public $status = TRUE;
 
@@ -241,4 +242,17 @@ class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface
     $this->new_revision = $new_revision;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
+    parent::postSave($storage, $update);
+
+    if (!$update) {
+      // Inform the plugin that this bundle has just been created.
+      $this->getType()->reactOnBundleCreated($this->id(), $this->getEntityTypeId());
+    }
+
+  }
+
 }
diff --git a/src/MediaBundleForm.php b/src/MediaBundleForm.php
index 014a538..e8d0b37 100644
--- a/src/MediaBundleForm.php
+++ b/src/MediaBundleForm.php
@@ -316,6 +316,7 @@ class MediaBundleForm extends EntityForm {
     $plugin_configuration = !empty($this->configurableInstances[$plugin]['plugin_config']) ? $this->configurableInstances[$plugin]['plugin_config'] : [];
     $instance = $this->mediaTypeManager->createInstance($plugin, $plugin_configuration);
     $instance->submitConfigurationForm($form, $form_state);
+
   }
 
   /**
diff --git a/src/MediaTypeBase.php b/src/MediaTypeBase.php
index a472e7d..87ef61b 100644
--- a/src/MediaTypeBase.php
+++ b/src/MediaTypeBase.php
@@ -3,14 +3,14 @@
 namespace Drupal\media_entity;
 
 use Drupal\Component\Plugin\PluginBase;
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Config\Config;
 use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Form\FormStateInterface;
 
 /**
  * Base implementation of media type plugin.
@@ -158,4 +158,14 @@ abstract class MediaTypeBase extends PluginBase implements MediaTypeInterface, C
     return 'media:' . $media->bundle() . ':' . $media->uuid();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function reactOnBundleCreated($bundle_name, $entity_type_id) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createDefaultSourceField($bundle_name) {}
+
 }
diff --git a/src/MediaTypeDefaultFieldTrait.php b/src/MediaTypeDefaultFieldTrait.php
new file mode 100644
index 0000000..83d40be
--- /dev/null
+++ b/src/MediaTypeDefaultFieldTrait.php
@@ -0,0 +1,161 @@
+<?php
+namespace Drupal\media_entity;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+
+
+/**
+ * To exhibit by derivatives of Drupal\media_entity\MediaTypeBase.
+ * 
+ * Implements most of the behaviour required for a single source field that may
+ * be populated with a default field upon creation of a bundle.
+ */
+trait MediaTypeDefaultFieldTrait {
+  use StringTranslationTrait;
+
+  /**
+   * Produce an array of allowed field types for the source field.
+   *
+   * @return array[string]
+   *   An array containing field types that the media type allows as its source
+   *   field.
+   */
+  abstract public function allowedSourceFieldTypes();
+
+  /**
+   * Return the default source field's name.
+   */
+  abstract public function defaultSourceFieldName();
+
+  /**
+   * Return the default source field's type.
+   */
+  abstract public function defaultSourceFieldType();
+
+  /**
+   * Return the default source field's label.
+   */
+  abstract public function defaultSourceFieldLabel();
+
+  /**
+   * Return the default source field's formatter.
+   */
+  abstract public function defaultSourceFieldFormatter();
+
+  /**
+   * Return the default source field's form widget.
+   */
+  abstract public function defaultSourceFieldWidget();
+
+  /**
+   * Produce a form fragment to configure the source field.
+   * 
+   * To be called from a media type's buildConfigurationForm() method.
+   * 
+   * @param array $form
+   *   The $form array as passed to the buildConfigurationForm().
+   * 
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   * @return array
+   */
+  protected function defaultFieldConfigurationForm(array $form, FormStateInterface $form_state) {
+    $options = ['' => $this->t('- None -')];
+    $allowed_field_types = $this->allowedSourceFieldTypes();
+    /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
+    $bundle = $form_state->getFormObject()->getEntity();
+    foreach ($this->entityFieldManager->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) {
+      if (in_array($field->getType(), $allowed_field_types) && !$field->getFieldStorageDefinition()
+          ->isBaseField()
+      ) {
+        $options[$field_name] = $field->getLabel();
+      }
+    }
+
+    // Select the source field. Only show when the bundle is not new, so there
+    // will potentially be fields to select.
+    $form['source_field'] = array(
+      '#type' => 'select',
+      '#title' => $this->t('Field with source information'),
+      '#default_value' => empty($this->configuration['source_field']) ? $this->defaultSourceFieldName() : $this->configuration['source_field'],
+      '#options' => $options,
+      '#access' => !$bundle->isNew(),
+    );
+
+    // Add a checkbox to allow the field being created automatically on save.
+    $form['create_source_field'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Create a source field automatically when saving this form.'),
+      '#description' => $this->t('If checked, a default field will be created and used as a source field. If you uncheck the field, you will need to create a field and revisit this form later to select it.'),
+      '#default_value' => TRUE,
+      '#access' => $bundle->isNew(),
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function reactOnBundleCreated($bundle_name, $entity_type_id) {
+    if (!empty($this->configuration['create_source_field'])) {
+      $this->createDefaultSourceField($bundle_name);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createDefaultSourceField($bundle_name) {
+
+    // @todo Sanity-check: defaultSourceFieldType is actually allowed.
+
+    // Create / load the field storage.
+    if (!$storage = FieldStorageConfig::loadByName('media', $this->defaultSourceFieldName())) {
+      $storage = FieldStorageConfig::create([
+        'field_name' => $this->defaultSourceFieldName(),
+        'entity_type' => 'media',
+        'type' => $this->defaultSourceFieldType(),
+      ]);
+      $storage->save();
+    }
+
+    // Create the field instance.
+    FieldConfig::create([
+      'entity_type' => 'media',
+      'field_name' => $this->defaultSourceFieldName(),
+      'label' => $this->defaultSourceFieldLabel(),
+      'required' => TRUE,
+      'bundle' => $bundle_name,
+    ])->save();
+
+    // Make the field visible on the form display.
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = EntityFormDisplay::create([
+      'targetEntityType' => 'media',
+      'bundle' => $bundle_name,
+      'mode' => 'default',
+      'status' => TRUE,
+    ]);
+    $form_display->setComponent($this->defaultSourceFieldName(), [
+      'type' => $this->defaultSourceFieldWidget(),
+    ])->save();
+
+    // Make the field visible on the media entity itself.
+    /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
+    $display = EntityViewDisplay::create([
+      'targetEntityType' => 'media',
+      'bundle' => $bundle_name,
+      'mode' => 'default',
+      'status' => TRUE,
+    ]);
+    $display->setComponent($this->defaultSourceFieldName(), [
+      'type' => $this->defaultSourceFieldFormatter(),
+    ])->save();
+  }
+
+}
diff --git a/src/MediaTypeInterface.php b/src/MediaTypeInterface.php
index 2a171c2..4cda123 100644
--- a/src/MediaTypeInterface.php
+++ b/src/MediaTypeInterface.php
@@ -2,8 +2,8 @@
 
 namespace Drupal\media_entity;
 
-use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 
 /**
@@ -85,4 +85,25 @@ interface MediaTypeInterface extends PluginInspectionInterface, ConfigurablePlug
    */
   public function getDefaultName(MediaInterface $media);
 
+  /**
+   * Take actions on bundle creation.
+   *
+   * @param string $bundle_name
+   *   The machine-name of the bundle created.
+   * @param string $entity_type_id
+   *   The entity type id.
+   */
+  public function reactOnBundleCreated($bundle_name, $entity_type_id);
+
+  /**
+   * Create a default source field.
+   *
+   * Plugins defining media bundles are strongly encouraged to provide a default
+   * source field to all fields used as source, when a new bundle is created.
+   *
+   * @param string $bundle_name
+   *   The machine-name of the bundle recently created.
+   */
+  public function createDefaultSourceField($bundle_name);
+
 }
diff --git a/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php b/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php
index 60d68a0..18571f1 100644
--- a/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php
+++ b/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php
@@ -2,7 +2,11 @@
 
 namespace Drupal\media_entity_test_type\Plugin\MediaEntity\Type;
 
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\media_entity\Plugin\MediaEntity\Type\Generic;
 
 /**
@@ -17,6 +21,21 @@ use Drupal\media_entity\Plugin\MediaEntity\Type\Generic;
 class TestType extends Generic {
 
   /**
+   * The name of the default source field on the media entity.
+   */
+  const MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME = 'field_media_test_type';
+
+  /**
+   * The id of the widget to be used when creating the default source field.
+   */
+  const MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_WIDGET = 'string_textfield';
+
+  /**
+   * The id of the formatter to be used when creating the default source field.
+   */
+  const MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_FORMATTER = 'string';
+
+  /**
    * {@inheritdoc}
    */
   public function providedFields() {
@@ -32,6 +51,7 @@ class TestType extends Generic {
   public function defaultConfiguration() {
     return [
       'test_config_value' => 'This is default value.',
+      'create_source_field' => TRUE,
     ];
   }
 
@@ -45,7 +65,96 @@ class TestType extends Generic {
       '#default_value' => empty($this->configuration['test_config_value']) ? NULL : $this->configuration['test_config_value'],
     ];
 
+    $options = [];
+    $allowed_field_types = ['string'];
+    /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
+    $bundle = $form_state->getFormObject()->getEntity();
+    foreach ($this->entityFieldManager->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) {
+      if (in_array($field->getType(), $allowed_field_types) && !$field->getFieldStorageDefinition()->isBaseField()) {
+        $options[$field_name] = $field->getLabel();
+      }
+    }
+
+    $form['source_field'] = array(
+      '#type' => 'select',
+      '#title' => $this->t('Field with source information'),
+      '#description' => $this->t('Field on media entity that stores the source information. You can create a bundle without selecting a value for this dropdown initially. This dropdown can be populated after adding fields to the bundle.'),
+      '#default_value' => empty($this->configuration['source_field']) ? self::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME : $this->configuration['source_field'],
+      '#options' => $options,
+    );
+
+    // Add a checkbox to allow the field being created automatically on save.
+    if (empty($this->configuration['source_field'])) {
+      $form['create_source_field'] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Create a source field automatically when saving this form.'),
+        '#description' => $this->t('If checked, a default field will be created and used as a source field. You can change this setting later.'),
+        '#default_value' => $this->configuration['create_source_field'],
+        '#access' => $bundle->isNew(),
+      ];
+    }
+
     return $form;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function reactOnBundleCreated($bundle_name, $entity_type_id) {
+    if (!empty($this->configuration['create_source_field'])) {
+      $this->createDefaultSourceField($bundle_name);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createDefaultSourceField($bundle_name) {
+
+    // Create / load the field storage.
+    if (!$storage = FieldStorageConfig ::loadByName('media', static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME)) {
+      $storage = FieldStorageConfig::create([
+        'field_name' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME,
+        'entity_type' => 'media',
+        'type' => 'string',
+      ]);
+      $storage->save();
+    }
+
+    // Create the field instance.
+    FieldConfig::create([
+      'entity_type' => 'media',
+      'field_name' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME,
+      'label' => $this->t('Tweet URL'),
+      'required' => TRUE,
+      'bundle' => $bundle_name,
+    ])->save();
+
+    // Make the field visible on the form display.
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = EntityFormDisplay::create([
+      'targetEntityType' => 'media',
+      'bundle' => $bundle_name,
+      'mode' => 'default',
+      'status' => TRUE,
+    ]);
+    $form_display->setComponent(static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME, [
+      'type' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_WIDGET,
+    ])->save();
+
+    // Make the field visible on the media entity itself.
+    /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
+    $display = EntityViewDisplay::create([
+      'targetEntityType' => 'media',
+      'bundle' => $bundle_name,
+      'mode' => 'default',
+      'status' => TRUE,
+    ]);
+    $display->setComponent(static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME, [
+      'type' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_FORMATTER,
+    ])->save();
+
+    // @TODO Evaluate if it's necessary to save the 'source_field' config value.
+  }
+
 }
