Rendering arbitrary field values without a parent entity in Drupal 8 I would like to expose to the user their choice of field formatters and the respective field formatter options. The selected formatter would then render an arbitrary array of items in the same format as a value for that field type, without any kind of parent entity.

Again, I want to render what looks to be an array of field values, without having an actual field or entity with a field value.

In Drupal 7 I could accomplish this using the following code (Gist formatted version):

// Render a file using the 'Generic file' formatter (a nice link with an icon):
$file = file_load(1);
$field = array('type' =&gt; 'file');
// File fields are stupid with their field values.
$items = array(0 =&gt; array('fid' =&gt; $file-&gt;fid) + (array) $file);
$display = array('type' =&gt; 'file_default');
$output = field_items_render($field, array(), $items, $display);
return drupal_render($output);

// Render node 1 with an entityreference formatter
$field = array('type' =&gt; 'entityreference');
$items = array(0 =&gt; array('target_id' =&gt; 1));
$display = array('type' =&gt; 'entityreference_label', 'settings' =&gt; array('link' =&gt; TRUE));
$output = field_items_render($field, array(), $items, $display);
return drupal_render($output);
// Outputs &lt;a href="/node/1"&gt;Title of node 1&lt;/a&gt;

function field_items_render(array $field, array $instance, array $items, array $display, $langcode = LANGUAGE_NONE) {
  $field += field_info_field_types($field['type']);

  $display += field_info_formatter_types($display['type']);

  $instance += array(
    'entity_type' =&gt; 'node',
    'bundle' =&gt; '_fake',
    'settings' =&gt; array(),
  );
  $instance['settings'] += $field['instance_settings'];

  $entity_type = 'node';
  $entity = NULL;
  $entities = array(0 =&gt; $entity);
  $entity_items = array(0 =&gt; &amp;$items);

  // Run hook_field_prepare_view() on the field module.
  $function = $field['module'] . '_field_prepare_view';
  if (function_exists($function)) {
    $function($entity_type, $entities, $field, $instances, $langcode, $entity_items);
  }

  // Run hook_field_formatter_prepare_view() on the formatter module.
  $function = $display['module'] . '_field_formatter_prepare_view';
  if (function_exists($function)) {
    $function($entity_type, $entities, $field, array(0 =&gt; $instance), $langcode, $entity_items, array(0 =&gt; $display));
  }

  // Run hook_field_formatter_View() on the formatter module.
  $function = $display['module'] . '_field_formatter_view';
  $result = $function($entity_type, NULL, $field, $instance, $langcode, $items, $display);

  return $result;
}


While I can do this in Drupal 7 very relatively easily, how can I accomplish the same in Drupal 8 (or at least help lead me down the right path through all the major parts of this)?
Yeah, you can't get around having an entity object, but it doesn't matter what it is, the only place where it's needed in the following code is FormatterBase::view(), to set #entity_type, which will later be used for the class name.

&lt;?php

use Drupal\Core\Field\FieldDefinition;
use Drupal\node\Entity\Node;

// Load the node, you can also create a temporary object or have your own
// dummy object that implements EntityInterface. (Might need ContentEntityInterface, not sure).
$node = Node::load(1);

// Create the field definition, some might need more settings, it currently
// doesn't load in the field type defaults. https://drupal.org/node/2116341
// Field name is only set to avoid broken CSS classes.
$definition = FieldDefinition::create('entity_reference')
  -&gt;setName('whatever')
  -&gt;setSetting('target_type', 'node');

/* @var \Drupal\Core\Field\FieldItemListInterface $items $items */
// Create a field item list object, 1 is the value, array('target_id' =&gt; 1)
// would work too, or multiple values. 1 is passed down from the list to the
// field item, which knows that an integer is the ID.
$items = \Drupal::typedDataManager()-&gt;create($definition, 1, $definition-&gt;getName(), $node);

/* @var \Drupal\Core\Field\FormatterInterface $formatter */
// Create the formatter plugin. Will use the default formatter for that field
// type if none is passed.
$formatter = \Drupal::service('plugin.manager.field.formatter')-&gt;getInstance(array(
  'field_definition' =&gt; $definition,
  'view_mode' =&gt; 'default',
  'configuration' =&gt; array(
    'label' =&gt; 'hidden',
    'type' =&gt; 'entityreference_label',
    'settings' =&gt; array('link' =&gt; TRUE),
  )
));

// Prepare, expects an array of items, keyed by parent entity ID, not sure if
// actually used, just array($items) worked too.
$formatter-&gt;prepareView(array($node-&gt;id() =&gt; $items));
print \Drupal::service('renderer')-&gt;renderRoot($formatter-&gt;view($items));


Yes, finding this out is not trivial, but I disagree with you that the 7.x code is relatively easy, it's just that you know the 7.x field API and internal magic callbacks very well. The main difference is that instead of building arbitrary array structures and passing them around, you need to find the right object/class/service and call methods on there. Once you found them, it's not that hard, FormatterPluginManager::getInstance() for example documents very well what it expects.