diff --git a/media_entity.module b/media_entity.module
index d54f773..9b157e5 100644
--- a/media_entity.module
+++ b/media_entity.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\media_entity\Entity\MediaBundle;
 
 /**
  * Implements hook_help().
diff --git a/src/Entity/MediaBundle.php b/src/Entity/MediaBundle.php
index 8833f82..0b16cdd 100644
--- a/src/Entity/MediaBundle.php
+++ b/src/Entity/MediaBundle.php
@@ -2,12 +2,16 @@
 
 namespace Drupal\media_entity\Entity;
 
-use Drupal\Core\Entity\EntityDescriptionInterface;
 use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+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;
 use Drupal\media_entity\MediaInterface;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Defines the Media bundle configuration entity.
@@ -44,6 +48,7 @@ use Drupal\media_entity\MediaInterface;
  *     "type_configuration",
  *     "field_map",
  *     "status",
+ *     "create_source_field",
  *   },
  *   links = {
  *     "add-form" = "/admin/structure/media/add",
@@ -121,7 +126,7 @@ class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface
   /**
    * Default status of this media bundle.
    *
-   * @var array
+   * @var bool
    */
   public $status = TRUE;
 
@@ -241,4 +246,62 @@ 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) {
+      // When creating new bundles, add also a source field, if configured to
+      // do so.
+      if (!$this->isSyncing() && empty($this->getTypeConfiguration()['source_field']) && !empty($this->getTypeConfiguration()['create_source_field'])) {
+        $media_type_manager = \Drupal::service('plugin.manager.media_entity.type');
+        /** @var \Drupal\media_entity\MediaTypeInterface $instance */
+        $instance = $media_type_manager->createInstance($this->getType()->getPluginId(), $this->getTypeConfiguration());
+        $default_field = $instance->getDefaultSourceField();
+
+        if (!empty($default_field['storage'])) {
+
+          // Save the field storage and create the instance.
+          $default_field['storage']->save();
+          FieldConfig::create([
+            'entity_type' => 'media',
+            'field_name' => $default_field['field_name'],
+            'label' => $default_field['label'],
+            'required' => TRUE,
+            'bundle' => $this->id(),
+          ])->save();
+
+          // Make the field visible on the form display.
+          /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+          $form_display = EntityFormDisplay::create([
+            'targetEntityType' => 'media',
+            'bundle' => $this->id(),
+            'mode' => 'default',
+            'status' => TRUE,
+          ]);
+          $form_display->setComponent($default_field['field_name'], [
+            'type' => $default_field['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' => $this->id(),
+            'mode' => 'default',
+            'status' => TRUE,
+          ]);
+          $display->setComponent($default_field['field_name'], [
+            'type' => $default_field['field_formatter'],
+          ])->save();
+
+        }
+
+      }
+    }
+
+  }
+
 }
diff --git a/src/MediaBundleForm.php b/src/MediaBundleForm.php
index 36365f3..3a0d121 100644
--- a/src/MediaBundleForm.php
+++ b/src/MediaBundleForm.php
@@ -313,6 +313,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..0041851 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,11 @@ abstract class MediaTypeBase extends PluginBase implements MediaTypeInterface, C
     return 'media:' . $media->bundle() . ':' . $media->uuid();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultSourceField() {
+    return [];
+  }
+
 }
diff --git a/src/MediaTypeInterface.php b/src/MediaTypeInterface.php
index 2a171c2..32a49e5 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,26 @@ interface MediaTypeInterface extends PluginInspectionInterface, ConfigurablePlug
    */
   public function getDefaultName(MediaInterface $media);
 
+  /**
+   * Provide a default source field.
+   *
+   * Plugins defining media bundles are suggested to implement this method and
+   * create a field that will be used as default source field, on bundle
+   * creation. Make sure this method returns unsaved entities, once these are
+   * only going to be saved and used if the user marked the option to use the
+   * default field provided.
+   *
+   * @return array
+   *   An associative array containing the following keys:
+   *   'storage' => \Drupal\field\Entity\FieldStorageConfig A config entity for
+   *   this field storage.
+   *   'field_name' => (string) The name to be used for the field instance.
+   *   'label' => (string) The label to be used for the field instance.
+   *   'field_widget' => (string) The id of the widget to use.
+   *   'field_formatter' => (string) The id of the formatter to use.
+   *   Note that the storage config entity need to be returned unsaved, and the
+   *   main form will be responsible for saving them.
+   */
+  public function getDefaultSourceField();
+
 }
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..a2c5049 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
@@ -3,6 +3,7 @@
 namespace Drupal\media_entity_test_type\Plugin\MediaEntity\Type;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\media_entity\Plugin\MediaEntity\Type\Generic;
 
 /**
@@ -17,6 +18,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 +48,7 @@ class TestType extends Generic {
   public function defaultConfiguration() {
     return [
       'test_config_value' => 'This is default value.',
+      'create_source_field' => TRUE,
     ];
   }
 
@@ -45,7 +62,56 @@ 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']) ? NULL : $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 getDefaultSourceField() {
+    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',
+      ]);
+    }
+    return [
+      'storage' => $storage,
+      'field_name' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_NAME,
+      'label' => $this->t('Test source field'),
+      'field_widget' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_WIDGET,
+      'field_formatter' => static::MEDIA_ENTITY_TEST_TYPE_DEFAULT_FIELD_FORMATTER,
+    ];
+  }
+
 }
diff --git a/tests/src/FunctionalJavascript/BundleCreationTest.php b/tests/src/FunctionalJavascript/BundleCreationTest.php
new file mode 100644
index 0000000..7483065
--- /dev/null
+++ b/tests/src/FunctionalJavascript/BundleCreationTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\Tests\media_entity\FunctionalJavascript;
+
+/**
+ * Tests the media bundle creation.
+ *
+ * @group media_entity
+ */
+class BundleCreationTest extends MediaEntityJavascriptTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'media_entity_test_type',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * Tests the media bundle creation form.
+   */
+  public function testBundleCreationForm() {
+
+    $page = $this->getSession()->getPage();
+
+    $this->drupalGet('admin/structure/media/add');
+
+    // Fill in a label to the bundle.
+    $page->fillField('label', 'Foo bundle');
+
+    // Select our test bundle type.
+    $this->assertSession()->fieldExists('type');
+    $this->assertSession()->optionExists('type', 'test_type');
+    $page->selectFieldOption('type', 'test_type');
+    $this->waitForAjaxToFinish();
+
+    // Make sure the checkbox for creating the source field is there and save.
+    $this->assertSession()->checkboxChecked('type_configuration[test_type][create_source_field]');
+    $page->pressButton('Save media bundle');
+
+    // Check whether the source field was correctly created.
+    // @TODO Finish me.
+
+  }
+
+}
diff --git a/tests/src/FunctionalJavascript/MediaEntityJavascriptTestBase.php b/tests/src/FunctionalJavascript/MediaEntityJavascriptTestBase.php
new file mode 100644
index 0000000..b47a672
--- /dev/null
+++ b/tests/src/FunctionalJavascript/MediaEntityJavascriptTestBase.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Drupal\Tests\media_entity\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Base class for Media Entity Javascript functional tests.
+ *
+ * @package Drupal\Tests\media_entity\FunctionalJavascript
+ */
+abstract class MediaEntityJavascriptTestBase extends JavascriptTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'media_entity',
+    'entity',
+    'system',
+    'image',
+    'user',
+    'views',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $account = $this->drupalCreateUser([
+      'administer media',
+      'administer media bundles',
+      // Media entity permissions.
+      'view media',
+      'create media',
+      'update media',
+      'update any media',
+      'delete media',
+      'delete any media',
+      'access media overview',
+    ]);
+    $this->drupalLogin($account);
+  }
+
+  /**
+   * Waits for jQuery to become ready and animations to complete.
+   */
+  protected function waitForAjaxToFinish() {
+    $this->assertSession()->assertWaitOnAjaxRequest();
+  }
+
+  /**
+   * Waits and asserts that a given element is visible.
+   *
+   * @param string $selector
+   *   The CSS selector.
+   * @param int $timeout
+   *   (Optional) Timeout in milliseconds, defaults to 1000.
+   * @param string $message
+   *   (Optional) Message to pass to assertJsCondition().
+   */
+  protected function waitUntilVisible($selector, $timeout = 1000, $message = '') {
+    $condition = "jQuery('" . $selector . ":visible').length > 0";
+    $this->assertJsCondition($condition, $timeout, $message);
+  }
+
+  /**
+   * Debugger method to save additional HTML output.
+   *
+   * The base class will only save browser output when accessing page using
+   * ::drupalGet and providing a printer class to PHPUnit. This method
+   * is intended for developers to help debug browser test failures and capture
+   * more verbose output.
+   */
+  protected function saveHtmlOutput() {
+    $out = $this->getSession()->getPage()->getContent();
+    // Ensure that any changes to variables in the other thread are picked up.
+    $this->refreshVariables();
+    if ($this->htmlOutputEnabled) {
+      $html_output = '<hr />Ending URL: ' . $this->getSession()->getCurrentUrl();
+      $html_output .= '<hr />' . $out;
+      $html_output .= $this->getHtmlOutputHeaders();
+      $this->htmlOutput($html_output);
+    }
+  }
+
+}
