diff --git a/entity_view_mode.api.php b/entity_view_mode.api.php
new file mode 100644
index 0000000..87a5d18
--- /dev/null
+++ b/entity_view_mode.api.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * API documentation for the entity_view_mode module.
+ */
+
+/**
+ * Describe the view modes for entity types.
+ *
+ * View modes let entities be displayed differently depending on the context.
+ * For instance, a node can be displayed differently on its own page ('full'
+ * mode), on the home page or taxonomy listings ('teaser' mode), or in an RSS
+ * feed ('rss' mode). Modules taking part in the display of the entity (notably
+ * the Field API) can adjust their behavior depending on the requested view
+ * mode. An additional 'default' view mode is available for all entity types.
+ * This view mode is not intended for actual entity display, but holds default
+ * display settings. For each available view mode, administrators can configure
+ * whether it should use its own set of field display settings, or just
+ * replicate the settings of the 'default' view mode, thus reducing the amount
+ * of display configurations to keep track of.
+ *
+ * Note: This hook is invoked inside an implementation of
+ * hook_entity_info_alter() so care must be taken not to call anything that
+ * will result in an additional, and hence recurisve call to entity_get_info().
+ *
+ * @return array
+ *   An associative array of all entity view modes, keyed by the entity
+ *   type name, and then the view mode name, with the following keys:
+ *   - label: The human-readable name of the view mode.
+ *   - custom_settings: A boolean specifying whether the view mode should by
+ *     default use its own custom field display settings. If FALSE, entities
+ *     displayed in this view mode will reuse the 'default' display settings
+ *     by default (e.g. right after the module exposing the view mode is
+ *     enabled), but administrators can later use the Field UI to apply custom
+ *     display settings specific to the view mode.
+ *
+ * @see entity_view_mode_entity_info_alter()
+ * @see hook_entity_view_mode_info_alter()
+ */
+function hook_entity_view_mode_info() {
+  $view_modes['user']['full'] = array(
+    'label' => t('User account'),
+  );
+  $view_modes['user']['compact'] = array(
+    'label' => t('Compact'),
+    'custom_settings' => TRUE,
+  );
+  return $view_modes;
+}
+
+/**
+ * Alter the view modes for entity types.
+ *
+ * Note: This hook is invoked inside an implementation of
+ * hook_entity_info_alter() so care must be taken not to call anything that
+ * will result in an additional, and hence recurisve call to entity_get_info().
+ *
+ * @param array $view_modes
+ *   An array of view modes, keyed first by entity type, then by view mode name.
+ *
+ * @see entity_view_mode_entity_info_alter()
+ * @see hook_entity_view_mode_info()
+ */
+function hook_entity_view_mode_info_alter(&$view_modes) {
+  $view_modes['user']['full']['custom_settings'] = TRUE;
+}
diff --git a/entity_view_mode.entity.inc b/entity_view_mode.entity.inc
new file mode 100644
index 0000000..92a6d3d
--- /dev/null
+++ b/entity_view_mode.entity.inc
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Entity view mode hook implementations for the entity_view_mode module.
+ */
+
+/**
+ * Implements of hook_entity_view_mode_info_alter().
+ */
+function entity_view_mode_entity_view_mode_info_alter(&$view_modes) {
+
+  // Add in the variable entity view modes will override hook-provided ones with the
+  // same machine name.
+  $custom_view_modes = variable_get('entity_view_modes', array());
+  foreach ($custom_view_modes as $type => $entity_info) {
+    foreach ($entity_info as $view_mode => $view_mode_info) {
+      $view_modes[$type][$view_mode] = $view_mode_info;
+    }
+  }
+}
diff --git a/entity_view_mode.module b/entity_view_mode.module
index 58548d4..b9efefe 100644
--- a/entity_view_mode.module
+++ b/entity_view_mode.module
@@ -1,6 +1,22 @@
 <?php
 
 /**
+ * Implements hook_hook_info().
+ */
+function entity_view_mode_hook_info() {
+  $hooks = array(
+    'entity_view_mode_info',
+    'entity_view_mode_info_alter',
+    'entity_view_mode_presave',
+    'entity_view_mode_insert',
+    'entity_view_mode_update',
+    'entity_view_mode_delete',
+  );
+
+  return array_fill_keys($hooks, array('group' => 'entity'));
+}
+
+/**
  * Implements hook_permission().
  */
 function entity_view_mode_permission() {
@@ -15,9 +31,18 @@ function entity_view_mode_permission() {
  * Implements hook_entity_info_alter().
  */
 function entity_view_mode_entity_info_alter(&$info) {
-  foreach (variable_get('entity_view_modes', array()) as $entity_type => $view_modes) {
-    if (isset($info[$entity_type]['view modes'])) {
-      $info[$entity_type]['view modes'] += $view_modes;
+  // First get all the hook-provided view modes.
+  $view_mode_info = module_invoke_all('entity_view_mode_info');
+  drupal_alter('entity_view_mode_info', $view_mode_info);
+
+  // Add in the combined custom entity view modes which override the existing
+  // view modes in the entity information.
+  foreach ($view_mode_info as $entity_type => $view_modes) {
+    if (isset($info[$entity_type])) {
+      if (!isset($info[$entity_type]['view modes'])) {
+        $info[$entity_type]['view modes'] = array();
+      }
+      $info[$entity_type]['view modes'] = $info[$entity_type]['view modes'] + $view_modes;
     }
   }
 }
