diff --git a/packages/react-dev-utils/WatchChangedNodeModulesPlugin.js b/packages/react-dev-utils/WatchChangedNodeModulesPlugin.js
new file mode 100644
index 00000000000..19475f5d182
--- /dev/null
+++ b/packages/react-dev-utils/WatchChangedNodeModulesPlugin.js
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+// This Webpack plugin ensures that any change in node_modules package.json forces a project rebuild.
+
+'use strict';
+
+var fs = require('fs');
+
+var timeout;
+
+class WatchChangedNodeModulesPlugin {
+  constructor(nodeModulesPath) {
+    this.nodeModulesPath = nodeModulesPath;
+  }
+
+  apply(compiler) {
+    fs.watch(
+      this.nodeModulesPath,
+      { persistent: false, recursive: true },
+      () => {
+        clearTimeout(timeout);
+        timeout = setTimeout(() => compiler.run(() => {}), 1000);
+      }
+    );
+  }
+}
+
+module.exports = WatchChangedNodeModulesPlugin;
diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json
index 05bddedae05..7f7e0c39cfc 100644
--- a/packages/react-dev-utils/package.json
+++ b/packages/react-dev-utils/package.json
@@ -33,6 +33,7 @@
     "openChrome.applescript",
     "printHostingInstructions.js",
     "WatchMissingNodeModulesPlugin.js",
+    "WatchChangedNodeModulesPlugin.js",
     "WebpackDevServerUtils.js",
     "webpackHotDevClient.js"
   ],
diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js
index c07819594b0..fd1572bedc5 100644
--- a/packages/react-scripts/config/webpack.config.dev.js
+++ b/packages/react-scripts/config/webpack.config.dev.js
@@ -15,6 +15,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
 const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
 const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
 const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
+const WatchChangedNodeModulesPlugin = require('react-dev-utils/WatchChangedNodeModulesPlugin');
 const eslintFormatter = require('react-dev-utils/eslintFormatter');
 const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
 const getClientEnvironment = require('./env');
@@ -333,11 +334,16 @@ module.exports = {
     // a plugin that prints an error when you attempt to do this.
     // See https://github.com/facebook/create-react-app/issues/240
     new CaseSensitivePathsPlugin(),
-    // If you require a missing module and then `npm install` it, you still have
+    // If you require a missing module and then `yarn add` it, you still have
     // to restart the development server for Webpack to discover it. This plugin
     // makes the discovery automatic so you don't have to restart.
     // See https://github.com/facebook/create-react-app/issues/186
     new WatchMissingNodeModulesPlugin(paths.appNodeModules),
+    // If you upgrade package version, you still have to restart the development
+    // server for Webpack to discover it. This plugin makes the discovery automatic
+    // so you don't have to restart.
+    // and https://github.com/facebook/create-react-app/issues/2956
+    new WatchChangedNodeModulesPlugin(paths.appNodeModules),
     // Moment.js is an extremely popular library that bundles large locale files
     // by default due to how Webpack interprets its code. This is a practical
     // solution that requires the user to opt into importing specific locales.