diff --git a/core/core.services.yml b/core/core.services.yml
index 5b0de75..c2ca77e 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -288,6 +288,12 @@ services:
     tags:
       - { name: page_cache_response_policy }
       - { name: dynamic_page_cache_response_policy }
+  composer.project_root:
+    class: Drupal\Core\Composer\ProjectRoot
+    arguments: ['@app.root']
+  composer.dev_dependency_finder:
+    class: Drupal\Core\Composer\Dependencies\DevDependencyFinder
+    arguments: ['@composer.project_root', '@string_translation']
   config.manager:
     class: Drupal\Core\Config\ConfigManager
     arguments: ['@entity.manager', '@config.factory', '@config.typed', '@string_translation', '@config.storage', '@event_dispatcher']
diff --git a/core/lib/Drupal/Core/Composer/Dependencies/DevDependencyFinder.php b/core/lib/Drupal/Core/Composer/Dependencies/DevDependencyFinder.php
new file mode 100644
index 0000000..1363e03
--- /dev/null
+++ b/core/lib/Drupal/Core/Composer/Dependencies/DevDependencyFinder.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Drupal\Core\Composer\Dependencies;
+
+use Drupal\Core\Composer\ProjectRootInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationInterface;
+
+/**
+ * Builds hook_requirements() info about Composer dev dependencies.
+ */
+class DevDependencyFinder {
+
+  use StringTranslationTrait;
+
+  /**
+   * The Composer project root service.
+   *
+   * @var \Drupal\Core\Composer\ProjectRootInterface
+   */
+  protected $projectRoot;
+
+  /**
+   * Constructor.
+   *
+   * @param \Drupal\Core\Composer\ProjectRootInterface $project_root
+   *   The Composer project root service.
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
+   *   The string translation service.
+   */
+  public function __construct(ProjectRootInterface $project_root, TranslationInterface $string_translation) {
+    $this->projectRoot = $project_root;
+    $this->setStringTranslation($string_translation);
+  }
+
+  /**
+   * Builds the Composer dev warning for the Drupal installation.
+   *
+   * @return array[]
+   *   Requirements array, suitable for hook_requirements().
+   *
+   * @see hook_requirements()
+   */
+  public function buildRequirements() {
+    $installed_dev = [];
+    // Get a list of installed packages.
+    $installed = array_keys($this->projectRoot->getInstalledPackages());
+    // Get the dev requirements for the root project.
+    $dev = $this->projectRoot->getDevRequirements();
+
+    foreach ($dev as $dev_requirement => $version) {
+      if (in_array($dev_requirement, $installed)) {
+        // @todo: Check version constraints for fewer false positives.
+        $installed_dev[] = $dev_requirement;
+      }
+    }
+
+    $requirements = [
+      'composer_dev_dependencies' => [
+        'title' => $this->t('Composer dev requirements'),
+      ],
+    ];
+    // If we have the same number of installed dev packages, then tell the user
+    // that they might need to change their site build workflow.
+    if (!empty($installed_dev) && (count($installed_dev) == count($dev))) {
+      $requirements['composer_dev_dependencies'] += [
+        'description' => $this->t('This Drupal installation appears to include development packages. This can lead to security issues. Read the <a href=":documentation">documentation on drupal.org</a>', [
+          ':documentation' => 'https://www.drupal.org/NEED_DOCS_HERE',
+        ]),
+        'severity' => REQUIREMENT_WARNING,
+      ];
+    }
+    else {
+      $requirements['composer_dev_dependencies'] += [
+        'description' => $this->t('This Drupal installation does not appear to have development packages installed. <a href=":documentation">Documentation on drupal.org</a>', [
+          ':documentation' => 'https://www.drupal.org/NEED_DOCS_HERE',
+        ]),
+        'severity' => REQUIREMENT_OK,
+      ];
+    }
+
+    return $requirements;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Composer/ProjectRoot.php b/core/lib/Drupal/Core/Composer/ProjectRoot.php
new file mode 100644
index 0000000..6185493
--- /dev/null
+++ b/core/lib/Drupal/Core/Composer/ProjectRoot.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\Core\Composer;
+
+/**
+ * Allow introversion of installed Composer dependencies.
+ */
+class ProjectRoot implements ProjectRootInterface {
+
+  protected $appRoot;
+
+  public function __construct($app_root) {
+    $this->appRoot = $app_root;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInstalledPackages() {
+    $installed_json_path = $this->appRoot . '/vendor/composer/installed.json';
+
+    // If installed.json does not exist, no packages are installed.
+    if (!file_exists($installed_json_path)) {
+      return [];
+    }
+
+    $installed_packages = [];
+    // Parse the list once and then cache it.
+    $json = file_get_contents($installed_json_path, FALSE);
+    foreach (json_decode($json) as $package) {
+      if (isset($package->name) && isset($package->version_normalized)) {
+        $installed_packages[$package->name] = $package->version_normalized;
+      }
+    }
+    return $installed_packages;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDevRequirements() {
+    // Since the default setup for Drupal is to have both a root package and a
+    // pre-installed package for drupal/core, we have to merge requirements to
+    // emulate the composer-merge plugin.
+    // @todo: Possibly change this when the drupal/core subtree split happens in
+    // https://www.drupal.org/node/2352091
+    return array_merge(
+      $this->getDevRequires($this->appRoot . '/composer.json'),
+      $this->getDevRequires($this->appRoot . '/core/composer.json')
+    );
+  }
+
+  /**
+   * Gathers the dev dependencies from a composer.json file.
+   *
+   * This method should never throw exceptions, since there are many different
+   * ways to structure Drupal as a Composer-based project.
+   *
+   * @param string $composer_file
+   *   Path to the composer.json file to read in.
+   *
+   * @return string[]
+   *   Associative array where the keys are the package names and the values are
+   *   version constraints. This is similar to the composer.json file's
+   *   require-dev array.
+   *
+   * @see https://getcomposer.org/doc/04-schema.md#require-dev
+   */
+  protected function getDevRequires($composer_file) {
+    $json = [];
+    $contents = file_get_contents($composer_file, FALSE);
+    if ($contents !== FALSE) {
+      $json = json_decode($contents, TRUE);
+    }
+    if (isset($json['require-dev'])) {
+      return $json['require-dev'];
+    }
+    return [];
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Composer/ProjectRootInterface.php b/core/lib/Drupal/Core/Composer/ProjectRootInterface.php
new file mode 100644
index 0000000..c59819b
--- /dev/null
+++ b/core/lib/Drupal/Core/Composer/ProjectRootInterface.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\Core\Composer;
+
+/**
+ * Find information about the Composer project for this site.
+ */
+interface ProjectRootInterface {
+
+  /**
+   * Gets Composer packages that are currently installed.
+   *
+   * @return string[]
+   *   An associative array of the packages which were installed by Composer.
+   *   Keys are package names and values are package versions. Example:
+   *   ['crell/api-problem' => '1.7.0']. Returns an empty array if no packages
+   *   have been installed.
+   */
+  public function getInstalledPackages();
+
+  /**
+   * Gets the development requirements for the Drupal installation.
+   *
+   * Note that since Drupal uses Wikimedia's composer-merge plugin, this method
+   * will return a combination of the root package and the drupal/core package.
+   *
+   * @return string[]
+   *   Associative array where the keys are the package names and the values are
+   *   version constraints. This is similar to the composer.json file's
+   *   require-dev array.
+   *
+   * @see https://getcomposer.org/doc/04-schema.md#require-dev
+   */
+  public function getDevRequirements();
+
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 6dc2663..f9158f9 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -68,6 +68,12 @@ function system_requirements($phase) {
         'severity' => REQUIREMENT_WARNING,
       );
     }
+
+    // Add warning about Composer-based dev requirements.
+    $requirements = array_merge(
+      $requirements,
+      \Drupal::service('composer.dev_dependency_finder')->buildRequirements()
+    );
   }
 
   // Web server information.
