diff --git a/core/modules/composer_dependency/composer.json b/core/modules/composer_dependency/composer.json
new file mode 100644
index 0000000..3b02fcf
--- /dev/null
+++ b/core/modules/composer_dependency/composer.json
@@ -0,0 +1,16 @@
+{
+    "name": "drupal/composer_dependency",
+    "version": "8.0.0",
+    "description": "A module that does stuff.",
+    "type": "drupal-module",
+    "license": "GPL-2.0+",
+    "authors": [
+        {
+            "name": "Paul Mitchum",
+            "email": "paul@mile23.com"
+        }
+    ],
+    "require": {
+        "crell/api-problem": "1.7"
+    }
+}
diff --git a/core/modules/composer_dependency/composer_dependency.info.yml b/core/modules/composer_dependency/composer_dependency.info.yml
new file mode 100644
index 0000000..cef5e88
--- /dev/null
+++ b/core/modules/composer_dependency/composer_dependency.info.yml
@@ -0,0 +1,6 @@
+name: Composer Dependency
+type: module
+description: 'Determines whether Composer-based dependencies are met.'
+package: Core
+version: VERSION
+core: 8.x
diff --git a/core/modules/composer_dependency/composer_dependency.install b/core/modules/composer_dependency/composer_dependency.install
new file mode 100644
index 0000000..c4b7e39
--- /dev/null
+++ b/core/modules/composer_dependency/composer_dependency.install
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for the book module.
+ */
+
+use Composer\Json\JsonFile;
+
+/**
+ * Implements hook_requirements().
+ */
+function composer_dependency_requirements($phase) {
+  // During the install phase, make it impossible to install a module which has
+  // Composer-based dependencies if Composer is not installed as a dependency.
+  if ($phase == 'install') {
+    // During the install phase, we won't have the drupal_repository service
+    // available, so we must create our own. Also, Drupal hasn't told the class
+    // loader about our classes, so we have to manually load the factory.
+    require_once __DIR__ . '/src/DrupalRepositoryFactory.php';
+    $factory = new Drupal\composer_dependency\DrupalRepositoryFactory(\Drupal::root());
+    try {
+      $drupal_dependencies = $factory->getDrupalRepository();
+    }
+    catch (\RuntimeException $e) {
+      $requirements['composer_dependency'] = array(
+        'title' => t('Composer is not present.'),
+        'severity' => REQUIREMENT_ERROR,
+        'description' => $e->getMessage(),
+      );
+      return $requirements;
+    }
+  }
+  if ($phase == 'runtime') {
+    $drupal_dependencies = NULL;
+    try {
+      $drupal_dependencies = \Drupal::service('composer_dependency.drupal_respository');
+    }
+    catch (\RuntimeException $e) {
+      $requirements['composer_dependency'] = array(
+        'title' => t('Composer is not present.'),
+        'severity' => REQUIREMENT_ERROR,
+        'description' => $e->getMessage(),
+      );
+      return $requirements;
+    }
+    if ($drupal_dependencies) {
+      // Composer is installed as a dependency.
+      // Discover all composer.json files.
+      $composer_paths = [];
+      $module_handler = \Drupal::moduleHandler();
+      $module_list = $module_handler->getModuleList();
+      foreach ($module_list as $name => $module) {
+        $path = $module->getPath() . '/composer.json';
+        if (file_exists($path)) {
+          $composer_paths[$name] = $path;
+        }
+      }
+      // Determine if our requirements are met.
+      $unmet_dependencies = [];
+      foreach ($composer_paths as $name => $json_path) {
+        $json_file = new JsonFile($json_path);
+        if (!$drupal_dependencies->areDependenciesMet($json_file)) {
+          $unmet_dependencies[] = $name;
+        }
+      }
+      if (count($unmet_dependencies)) {
+        $requirements['composer_dependency'] = array(
+          'title' => t('Composer is present.'),
+          'severity' => REQUIREMENT_ERROR,
+          'description' => t('Composer dependencies are missing for: ') . implode(', ', $unmet_dependencies) . '. There are currently no instructions for how to solve this.',
+        );
+        return $requirements;
+      }
+
+      $modules = implode(', ', array_keys($composer_paths));
+      $requirements['composer_dependency'] = array(
+        'title' => t('Composer is present.'),
+        'severity' => REQUIREMENT_INFO,
+        'description' => t('Composer dependencies are met for: ') . $modules,
+      );
+    }
+  }
+  return $requirements;
+}
diff --git a/core/modules/composer_dependency/composer_dependency.module b/core/modules/composer_dependency/composer_dependency.module
new file mode 100644
index 0000000..07e00de
--- /dev/null
+++ b/core/modules/composer_dependency/composer_dependency.module
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Empty .module file for composer_dependency.
+ *
+ * Other modules can declare their dependence on this one, and it will determine
+ * whether Composer-based dependencies are met.
+ *
+ * You declare Composer-based dependencies for your module by adding a
+ * composer.json file to the top-level directory of your module. This is a
+ * plain-vanilla composer.json file.
+ *
+ * You should then have your module declare its dependency on this one.
+ *
+ * This module does not give you a way to manage these dependencies; it only
+ * checks whether they are met.
+ *
+ * Since this module uses the Composer package itself to determine whether
+ * dependencie are met, it will fail to install if Composer is not installed as
+ * a dependency of Drupal. This will cause modules which depend on it to also
+ * fail to install.
+ *
+ * You can fix this dependency problem from the command line, like this:
+ * @code
+ * cd core
+ * composer require composer/composer
+ * @endcode
+ *
+ * After this basic dependency is met, you can try to install the module again,
+ * and then visit your site's status page to determine whether other
+ * Composer-based dependencies are sill unmet.
+ */
diff --git a/core/modules/composer_dependency/composer_dependency.services.yml b/core/modules/composer_dependency/composer_dependency.services.yml
new file mode 100644
index 0000000..64cbf57
--- /dev/null
+++ b/core/modules/composer_dependency/composer_dependency.services.yml
@@ -0,0 +1,9 @@
+services:
+    composer_dependency.drupal_respository:
+        class: Drupal\composer_dependency\DrupalRepository
+        factory: composer_dependency.drupal_respository.factory:getDrupalRepository
+        tags:
+          - { name: parameter_service }
+    composer_dependency.drupal_respository.factory:
+        class: Drupal\composer_dependency\DrupalRepositoryFactory
+        arguments: ['@app.root']
diff --git a/core/modules/composer_dependency/src/DrupalRepository.php b/core/modules/composer_dependency/src/DrupalRepository.php
new file mode 100644
index 0000000..49fe707
--- /dev/null
+++ b/core/modules/composer_dependency/src/DrupalRepository.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ */
+
+namespace Drupal\composer_dependency;
+
+use Composer\Repository\InstalledFilesystemRepository;
+use Composer\Json\JsonFile;
+use Composer\Package\Loader\ArrayLoader;
+use Composer\Package\Loader\JsonLoader;
+use Composer\Package\Package;
+
+/**
+ * A service to query the Composer vendor repository for Drupal.
+ */
+class DrupalRepository extends InstalledFilesystemRepository {
+
+  /**
+   *
+   * @param string|SplString $app_root
+   */
+  public function __construct($app_root) {
+    $installed_json = (string) $app_root . '/core/vendor/composer/installed.json';
+    parent::__construct(new JsonFile($installed_json));
+  }
+
+  /**
+   * Determine whether a composer.json file depends on a package not present.
+   *
+   * Excludes require-dev (for now).
+   *
+   * @param JsonFile $json_file
+   *   A composer.json file, typically from a module.
+   *
+   * @return bool
+   *   TRUE if all dependencies in composer.json file are met. FALSE otherwise.
+   */
+  public function areDependenciesMet(JsonFile $json_file) {
+    // There has to be a better way to do this.
+    // Make a JSON loader to load JSON into our ArrayLoader.
+    $json_loader = new JsonLoader(new ArrayLoader());
+    // Load the JSON into a package.
+    $json_package = $json_loader->load($json_file);
+    // Get the array of requirements.
+    $requirements = $json_package->getRequires();
+    $unmet = [];
+    foreach ($requirements as $name => $link) {
+      // Each requirement is actually a Link object, which we must resolve into
+      // a package.
+      $package = new Package($link->getTarget(), $link->getConstraint(), $link->getPrettyConstraint());
+      // Finally ask the Drupal repo if it has this package.
+      if (!$this->findPackage($package->getName(), $package->getPrettyVersion())) {
+        $unmet[$name] = $package;
+      }
+    }
+    return count($unmet) ? FALSE : TRUE;
+  }
+
+}
diff --git a/core/modules/composer_dependency/src/DrupalRepositoryFactory.php b/core/modules/composer_dependency/src/DrupalRepositoryFactory.php
new file mode 100644
index 0000000..e4b6d374
--- /dev/null
+++ b/core/modules/composer_dependency/src/DrupalRepositoryFactory.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ */
+
+namespace Drupal\composer_dependency;
+
+/**
+ * Factory class for the drupal_repository service.
+ */
+class DrupalRepositoryFactory {
+
+  protected $appRoot;
+
+  public function __construct($app_root) {
+    $this->appRoot = (string) $app_root;
+  }
+
+  public function getDrupalRepository() {
+    // We look for InstalledFilesystemRepository because it's the superclass of
+    // DrupalRepository.
+    if (!class_exists('\Composer\Repository\InstalledFilesystemRepository')) {
+      throw new \RuntimeException('Composer must be installed as a dependency before its services can be used.');
+    }
+    // We need to require DrupalRepository's PHP file because this method can be
+    // run during the install phase, and when Composer is not installed as a
+    // requirement. We can do this here because we know
+    // InstalledFilesystemRepository is available.
+    // @todo: Determine a better way to do this.
+    require_once __DIR__ . '/DrupalRepository.php';
+    return new DrupalRepository($this->appRoot);
+  }
+
+}
